Executing a signal after event loop
up vote
1
down vote
favorite
In my .qml file, when a Button
is pressed, it emits a signal, and some action is taken. This action takes a long time (it is encrypting data) and I want the button to "unpush" itself before this action starts, so I can show a progress bar on top.
I know Qt has event loop, and somehow, I need this signal to be emitted after this event loop , or when the GUI completes the Paint() of all objects, so the button is shown unpressed.
How is this done?
This is the code that is being executed on the signal, the heavy process is aewm_obj.save_account(key,account)
, it takes 2 seconds on desktop PC and 10 seconds on Android:
function save_account()
if (fld_password1.length===0)
if (account.type==WalletAccount.WACCT_TYPE_FULL)
return
if (fld_password1.text!==fld_password2.text)
console.log("passwords do not match")
else
btn_save.enabled=true;
if (account.type==WalletAccount.WACCT_TYPE_FULL)
key.password=fld_password1.text
account.password=fld_password1.text
btn_save.enabled=false
encrypting_message.open()
if (aewm_obj.save_account(key,account))
encrypting_message.close()
accounts_root.back_to_accounts()
else
encrypting_message.close()
The problem is, the dialog with the progress bar is shown after the heavy process finishes, however it was called before. This happens because the event loop to show and hide components is processed too late.
qt qml
|
show 6 more comments
up vote
1
down vote
favorite
In my .qml file, when a Button
is pressed, it emits a signal, and some action is taken. This action takes a long time (it is encrypting data) and I want the button to "unpush" itself before this action starts, so I can show a progress bar on top.
I know Qt has event loop, and somehow, I need this signal to be emitted after this event loop , or when the GUI completes the Paint() of all objects, so the button is shown unpressed.
How is this done?
This is the code that is being executed on the signal, the heavy process is aewm_obj.save_account(key,account)
, it takes 2 seconds on desktop PC and 10 seconds on Android:
function save_account()
if (fld_password1.length===0)
if (account.type==WalletAccount.WACCT_TYPE_FULL)
return
if (fld_password1.text!==fld_password2.text)
console.log("passwords do not match")
else
btn_save.enabled=true;
if (account.type==WalletAccount.WACCT_TYPE_FULL)
key.password=fld_password1.text
account.password=fld_password1.text
btn_save.enabled=false
encrypting_message.open()
if (aewm_obj.save_account(key,account))
encrypting_message.close()
accounts_root.back_to_accounts()
else
encrypting_message.close()
The problem is, the dialog with the progress bar is shown after the heavy process finishes, however it was called before. This happens because the event loop to show and hide components is processed too late.
qt qml
Do you execute the heavy process in QML or C++?
– eyllanesc
Nov 8 at 21:50
the heavy process is in C++
– Nulik
Nov 8 at 21:50
then you must execute it in a thread
– eyllanesc
Nov 8 at 21:51
hmm, this is a bit complicated, because the user can go to another screen and that's gonna be undefined behaviour... Maybe I can call a timer few milliseconds after button has been pressed?
– Nulik
Nov 8 at 21:55
can I force a "repaint" of the screen somehow, so my "dialog" with progress bar shows before the heavy process?
– Nulik
Nov 8 at 22:00
|
show 6 more comments
up vote
1
down vote
favorite
up vote
1
down vote
favorite
In my .qml file, when a Button
is pressed, it emits a signal, and some action is taken. This action takes a long time (it is encrypting data) and I want the button to "unpush" itself before this action starts, so I can show a progress bar on top.
I know Qt has event loop, and somehow, I need this signal to be emitted after this event loop , or when the GUI completes the Paint() of all objects, so the button is shown unpressed.
How is this done?
This is the code that is being executed on the signal, the heavy process is aewm_obj.save_account(key,account)
, it takes 2 seconds on desktop PC and 10 seconds on Android:
function save_account()
if (fld_password1.length===0)
if (account.type==WalletAccount.WACCT_TYPE_FULL)
return
if (fld_password1.text!==fld_password2.text)
console.log("passwords do not match")
else
btn_save.enabled=true;
if (account.type==WalletAccount.WACCT_TYPE_FULL)
key.password=fld_password1.text
account.password=fld_password1.text
btn_save.enabled=false
encrypting_message.open()
if (aewm_obj.save_account(key,account))
encrypting_message.close()
accounts_root.back_to_accounts()
else
encrypting_message.close()
The problem is, the dialog with the progress bar is shown after the heavy process finishes, however it was called before. This happens because the event loop to show and hide components is processed too late.
qt qml
In my .qml file, when a Button
is pressed, it emits a signal, and some action is taken. This action takes a long time (it is encrypting data) and I want the button to "unpush" itself before this action starts, so I can show a progress bar on top.
I know Qt has event loop, and somehow, I need this signal to be emitted after this event loop , or when the GUI completes the Paint() of all objects, so the button is shown unpressed.
How is this done?
This is the code that is being executed on the signal, the heavy process is aewm_obj.save_account(key,account)
, it takes 2 seconds on desktop PC and 10 seconds on Android:
function save_account()
if (fld_password1.length===0)
if (account.type==WalletAccount.WACCT_TYPE_FULL)
return
if (fld_password1.text!==fld_password2.text)
console.log("passwords do not match")
else
btn_save.enabled=true;
if (account.type==WalletAccount.WACCT_TYPE_FULL)
key.password=fld_password1.text
account.password=fld_password1.text
btn_save.enabled=false
encrypting_message.open()
if (aewm_obj.save_account(key,account))
encrypting_message.close()
accounts_root.back_to_accounts()
else
encrypting_message.close()
The problem is, the dialog with the progress bar is shown after the heavy process finishes, however it was called before. This happens because the event loop to show and hide components is processed too late.
qt qml
qt qml
edited Nov 8 at 22:04
asked Nov 8 at 21:47
Nulik
1,59812148
1,59812148
Do you execute the heavy process in QML or C++?
– eyllanesc
Nov 8 at 21:50
the heavy process is in C++
– Nulik
Nov 8 at 21:50
then you must execute it in a thread
– eyllanesc
Nov 8 at 21:51
hmm, this is a bit complicated, because the user can go to another screen and that's gonna be undefined behaviour... Maybe I can call a timer few milliseconds after button has been pressed?
– Nulik
Nov 8 at 21:55
can I force a "repaint" of the screen somehow, so my "dialog" with progress bar shows before the heavy process?
– Nulik
Nov 8 at 22:00
|
show 6 more comments
Do you execute the heavy process in QML or C++?
– eyllanesc
Nov 8 at 21:50
the heavy process is in C++
– Nulik
Nov 8 at 21:50
then you must execute it in a thread
– eyllanesc
Nov 8 at 21:51
hmm, this is a bit complicated, because the user can go to another screen and that's gonna be undefined behaviour... Maybe I can call a timer few milliseconds after button has been pressed?
– Nulik
Nov 8 at 21:55
can I force a "repaint" of the screen somehow, so my "dialog" with progress bar shows before the heavy process?
– Nulik
Nov 8 at 22:00
Do you execute the heavy process in QML or C++?
– eyllanesc
Nov 8 at 21:50
Do you execute the heavy process in QML or C++?
– eyllanesc
Nov 8 at 21:50
the heavy process is in C++
– Nulik
Nov 8 at 21:50
the heavy process is in C++
– Nulik
Nov 8 at 21:50
then you must execute it in a thread
– eyllanesc
Nov 8 at 21:51
then you must execute it in a thread
– eyllanesc
Nov 8 at 21:51
hmm, this is a bit complicated, because the user can go to another screen and that's gonna be undefined behaviour... Maybe I can call a timer few milliseconds after button has been pressed?
– Nulik
Nov 8 at 21:55
hmm, this is a bit complicated, because the user can go to another screen and that's gonna be undefined behaviour... Maybe I can call a timer few milliseconds after button has been pressed?
– Nulik
Nov 8 at 21:55
can I force a "repaint" of the screen somehow, so my "dialog" with progress bar shows before the heavy process?
– Nulik
Nov 8 at 22:00
can I force a "repaint" of the screen somehow, so my "dialog" with progress bar shows before the heavy process?
– Nulik
Nov 8 at 22:00
|
show 6 more comments
2 Answers
2
active
oldest
votes
up vote
1
down vote
Use a single shot timer with a timeout of 0 to queue up an event that will be triggered after returning to the event loop. In C++ this typically looks like:
QTimer::singleShot(0, /* do something */ );
The QML equivalent is:
Timer
interval: 0; running: true; repeat: false
onTriggered: /* do something */
Maybe '0' does not work. I am using '10' for such solutions. However this answer should fix the problem.
– sk2212
Nov 9 at 14:11
1
@sk2212 "Maybe 0 does not work"?! There is no maybe. Using anything but 0 has larger overhead since it actually creates a system timer, when there is no need for it. All you need is a zero-duration timer, that is not really a timer but an indication that the operation is to be performed after the event queue is emptied.
– Kuba Ober
Nov 9 at 16:10
1
In C++, you'd not use a timer, butQMetaObject::invokeMethod( /* do something */, Qt::QueuedConnection);
. In QML,Qt.callLater
does that job - but c.f. QTBUG-59809!
– Kuba Ober
Nov 9 at 16:13
1
Well, using a QTimer::singleShot(0, ...) and doing a the invokeMethod results in exactly the same path taken. I find the 0-timer way more readable than the invoke method.
– André
Nov 9 at 19:46
actually,interval
must be something like 50,running
must be false. But it works nicely. Thanks
– Nulik
Nov 10 at 23:11
|
show 3 more comments
up vote
-1
down vote
After reading this article: https://doc.qt.io/archives/qq/qq27-responsive-guis.html
I have added code to my C++ function to process all the events before it starts the heavy process. This way, I empty event queue and the GUI updates automatically showing the progress bar dialog. (a sort of repaint() of all QML objects)
for (int i=0; i<10000; i++)
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
The delay caused by this loop is unnoticeable compared to the 2 seconds of processing time. The 10,000 iterations are needed on Android, on desktop 10 iterations is enough. Using small amount of iterations, will show the dialog not at full opacity, due to fade effects.
This seems bad design and not very flexible. Why not use a worker thread and a progress bar? You can disable UI interaction during that time but the UI stays responsive with updates.
– Jan Win
Nov 9 at 9:35
1
TheprocessEvents
call exposes your entire codebase to reentrancy, and I bet that you didn't design your code with reentrancy in mind. Don't do that.
– Kuba Ober
Nov 9 at 16:15
reentrancy is when it is interruped by hadware interrupt (or soft interrupt), here, it is not reentrancy, since I am interrupting it in a safe place. During this interrupt the local stack is not being changed, process objects are not being changed. global vars may be changed, but that's why they are global vars. It is just quick patch for the problem, I will rewrite it in the future with a timer on QML side.
– Nulik
Nov 9 at 18:55
No. Reentrancy means that a function not designed to do so is on the call stack two or more times in a given thread. AndprocessEvents
can end up calling any method in your code that would be callable as a result of event processing, I.e. timers, UI interaction including windows getting closed, communications – heck, you might start doing application-exit cleanup tasks within thatprocessEvents
. And you simply should not block the event loop period. Do your computation asynchronously. It’s amenable to it. Use the concurrent pramework of standard C++ async primitives.
– Kuba Ober
Nov 12 at 12:47
Interrupt handling can cause reentrancy, but is hardly the only way of it happening. Recall that on Windows, event processing can invoke IO completion as well, so both Qt and the OS itself may invoke code you never designed to be invoked.
– Kuba Ober
Nov 12 at 12:51
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Use a single shot timer with a timeout of 0 to queue up an event that will be triggered after returning to the event loop. In C++ this typically looks like:
QTimer::singleShot(0, /* do something */ );
The QML equivalent is:
Timer
interval: 0; running: true; repeat: false
onTriggered: /* do something */
Maybe '0' does not work. I am using '10' for such solutions. However this answer should fix the problem.
– sk2212
Nov 9 at 14:11
1
@sk2212 "Maybe 0 does not work"?! There is no maybe. Using anything but 0 has larger overhead since it actually creates a system timer, when there is no need for it. All you need is a zero-duration timer, that is not really a timer but an indication that the operation is to be performed after the event queue is emptied.
– Kuba Ober
Nov 9 at 16:10
1
In C++, you'd not use a timer, butQMetaObject::invokeMethod( /* do something */, Qt::QueuedConnection);
. In QML,Qt.callLater
does that job - but c.f. QTBUG-59809!
– Kuba Ober
Nov 9 at 16:13
1
Well, using a QTimer::singleShot(0, ...) and doing a the invokeMethod results in exactly the same path taken. I find the 0-timer way more readable than the invoke method.
– André
Nov 9 at 19:46
actually,interval
must be something like 50,running
must be false. But it works nicely. Thanks
– Nulik
Nov 10 at 23:11
|
show 3 more comments
up vote
1
down vote
Use a single shot timer with a timeout of 0 to queue up an event that will be triggered after returning to the event loop. In C++ this typically looks like:
QTimer::singleShot(0, /* do something */ );
The QML equivalent is:
Timer
interval: 0; running: true; repeat: false
onTriggered: /* do something */
Maybe '0' does not work. I am using '10' for such solutions. However this answer should fix the problem.
– sk2212
Nov 9 at 14:11
1
@sk2212 "Maybe 0 does not work"?! There is no maybe. Using anything but 0 has larger overhead since it actually creates a system timer, when there is no need for it. All you need is a zero-duration timer, that is not really a timer but an indication that the operation is to be performed after the event queue is emptied.
– Kuba Ober
Nov 9 at 16:10
1
In C++, you'd not use a timer, butQMetaObject::invokeMethod( /* do something */, Qt::QueuedConnection);
. In QML,Qt.callLater
does that job - but c.f. QTBUG-59809!
– Kuba Ober
Nov 9 at 16:13
1
Well, using a QTimer::singleShot(0, ...) and doing a the invokeMethod results in exactly the same path taken. I find the 0-timer way more readable than the invoke method.
– André
Nov 9 at 19:46
actually,interval
must be something like 50,running
must be false. But it works nicely. Thanks
– Nulik
Nov 10 at 23:11
|
show 3 more comments
up vote
1
down vote
up vote
1
down vote
Use a single shot timer with a timeout of 0 to queue up an event that will be triggered after returning to the event loop. In C++ this typically looks like:
QTimer::singleShot(0, /* do something */ );
The QML equivalent is:
Timer
interval: 0; running: true; repeat: false
onTriggered: /* do something */
Use a single shot timer with a timeout of 0 to queue up an event that will be triggered after returning to the event loop. In C++ this typically looks like:
QTimer::singleShot(0, /* do something */ );
The QML equivalent is:
Timer
interval: 0; running: true; repeat: false
onTriggered: /* do something */
edited Nov 9 at 20:13
answered Nov 9 at 2:44
Jason Haslam
1,203513
1,203513
Maybe '0' does not work. I am using '10' for such solutions. However this answer should fix the problem.
– sk2212
Nov 9 at 14:11
1
@sk2212 "Maybe 0 does not work"?! There is no maybe. Using anything but 0 has larger overhead since it actually creates a system timer, when there is no need for it. All you need is a zero-duration timer, that is not really a timer but an indication that the operation is to be performed after the event queue is emptied.
– Kuba Ober
Nov 9 at 16:10
1
In C++, you'd not use a timer, butQMetaObject::invokeMethod( /* do something */, Qt::QueuedConnection);
. In QML,Qt.callLater
does that job - but c.f. QTBUG-59809!
– Kuba Ober
Nov 9 at 16:13
1
Well, using a QTimer::singleShot(0, ...) and doing a the invokeMethod results in exactly the same path taken. I find the 0-timer way more readable than the invoke method.
– André
Nov 9 at 19:46
actually,interval
must be something like 50,running
must be false. But it works nicely. Thanks
– Nulik
Nov 10 at 23:11
|
show 3 more comments
Maybe '0' does not work. I am using '10' for such solutions. However this answer should fix the problem.
– sk2212
Nov 9 at 14:11
1
@sk2212 "Maybe 0 does not work"?! There is no maybe. Using anything but 0 has larger overhead since it actually creates a system timer, when there is no need for it. All you need is a zero-duration timer, that is not really a timer but an indication that the operation is to be performed after the event queue is emptied.
– Kuba Ober
Nov 9 at 16:10
1
In C++, you'd not use a timer, butQMetaObject::invokeMethod( /* do something */, Qt::QueuedConnection);
. In QML,Qt.callLater
does that job - but c.f. QTBUG-59809!
– Kuba Ober
Nov 9 at 16:13
1
Well, using a QTimer::singleShot(0, ...) and doing a the invokeMethod results in exactly the same path taken. I find the 0-timer way more readable than the invoke method.
– André
Nov 9 at 19:46
actually,interval
must be something like 50,running
must be false. But it works nicely. Thanks
– Nulik
Nov 10 at 23:11
Maybe '0' does not work. I am using '10' for such solutions. However this answer should fix the problem.
– sk2212
Nov 9 at 14:11
Maybe '0' does not work. I am using '10' for such solutions. However this answer should fix the problem.
– sk2212
Nov 9 at 14:11
1
1
@sk2212 "Maybe 0 does not work"?! There is no maybe. Using anything but 0 has larger overhead since it actually creates a system timer, when there is no need for it. All you need is a zero-duration timer, that is not really a timer but an indication that the operation is to be performed after the event queue is emptied.
– Kuba Ober
Nov 9 at 16:10
@sk2212 "Maybe 0 does not work"?! There is no maybe. Using anything but 0 has larger overhead since it actually creates a system timer, when there is no need for it. All you need is a zero-duration timer, that is not really a timer but an indication that the operation is to be performed after the event queue is emptied.
– Kuba Ober
Nov 9 at 16:10
1
1
In C++, you'd not use a timer, but
QMetaObject::invokeMethod( /* do something */, Qt::QueuedConnection);
. In QML, Qt.callLater
does that job - but c.f. QTBUG-59809!– Kuba Ober
Nov 9 at 16:13
In C++, you'd not use a timer, but
QMetaObject::invokeMethod( /* do something */, Qt::QueuedConnection);
. In QML, Qt.callLater
does that job - but c.f. QTBUG-59809!– Kuba Ober
Nov 9 at 16:13
1
1
Well, using a QTimer::singleShot(0, ...) and doing a the invokeMethod results in exactly the same path taken. I find the 0-timer way more readable than the invoke method.
– André
Nov 9 at 19:46
Well, using a QTimer::singleShot(0, ...) and doing a the invokeMethod results in exactly the same path taken. I find the 0-timer way more readable than the invoke method.
– André
Nov 9 at 19:46
actually,
interval
must be something like 50, running
must be false. But it works nicely. Thanks– Nulik
Nov 10 at 23:11
actually,
interval
must be something like 50, running
must be false. But it works nicely. Thanks– Nulik
Nov 10 at 23:11
|
show 3 more comments
up vote
-1
down vote
After reading this article: https://doc.qt.io/archives/qq/qq27-responsive-guis.html
I have added code to my C++ function to process all the events before it starts the heavy process. This way, I empty event queue and the GUI updates automatically showing the progress bar dialog. (a sort of repaint() of all QML objects)
for (int i=0; i<10000; i++)
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
The delay caused by this loop is unnoticeable compared to the 2 seconds of processing time. The 10,000 iterations are needed on Android, on desktop 10 iterations is enough. Using small amount of iterations, will show the dialog not at full opacity, due to fade effects.
This seems bad design and not very flexible. Why not use a worker thread and a progress bar? You can disable UI interaction during that time but the UI stays responsive with updates.
– Jan Win
Nov 9 at 9:35
1
TheprocessEvents
call exposes your entire codebase to reentrancy, and I bet that you didn't design your code with reentrancy in mind. Don't do that.
– Kuba Ober
Nov 9 at 16:15
reentrancy is when it is interruped by hadware interrupt (or soft interrupt), here, it is not reentrancy, since I am interrupting it in a safe place. During this interrupt the local stack is not being changed, process objects are not being changed. global vars may be changed, but that's why they are global vars. It is just quick patch for the problem, I will rewrite it in the future with a timer on QML side.
– Nulik
Nov 9 at 18:55
No. Reentrancy means that a function not designed to do so is on the call stack two or more times in a given thread. AndprocessEvents
can end up calling any method in your code that would be callable as a result of event processing, I.e. timers, UI interaction including windows getting closed, communications – heck, you might start doing application-exit cleanup tasks within thatprocessEvents
. And you simply should not block the event loop period. Do your computation asynchronously. It’s amenable to it. Use the concurrent pramework of standard C++ async primitives.
– Kuba Ober
Nov 12 at 12:47
Interrupt handling can cause reentrancy, but is hardly the only way of it happening. Recall that on Windows, event processing can invoke IO completion as well, so both Qt and the OS itself may invoke code you never designed to be invoked.
– Kuba Ober
Nov 12 at 12:51
add a comment |
up vote
-1
down vote
After reading this article: https://doc.qt.io/archives/qq/qq27-responsive-guis.html
I have added code to my C++ function to process all the events before it starts the heavy process. This way, I empty event queue and the GUI updates automatically showing the progress bar dialog. (a sort of repaint() of all QML objects)
for (int i=0; i<10000; i++)
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
The delay caused by this loop is unnoticeable compared to the 2 seconds of processing time. The 10,000 iterations are needed on Android, on desktop 10 iterations is enough. Using small amount of iterations, will show the dialog not at full opacity, due to fade effects.
This seems bad design and not very flexible. Why not use a worker thread and a progress bar? You can disable UI interaction during that time but the UI stays responsive with updates.
– Jan Win
Nov 9 at 9:35
1
TheprocessEvents
call exposes your entire codebase to reentrancy, and I bet that you didn't design your code with reentrancy in mind. Don't do that.
– Kuba Ober
Nov 9 at 16:15
reentrancy is when it is interruped by hadware interrupt (or soft interrupt), here, it is not reentrancy, since I am interrupting it in a safe place. During this interrupt the local stack is not being changed, process objects are not being changed. global vars may be changed, but that's why they are global vars. It is just quick patch for the problem, I will rewrite it in the future with a timer on QML side.
– Nulik
Nov 9 at 18:55
No. Reentrancy means that a function not designed to do so is on the call stack two or more times in a given thread. AndprocessEvents
can end up calling any method in your code that would be callable as a result of event processing, I.e. timers, UI interaction including windows getting closed, communications – heck, you might start doing application-exit cleanup tasks within thatprocessEvents
. And you simply should not block the event loop period. Do your computation asynchronously. It’s amenable to it. Use the concurrent pramework of standard C++ async primitives.
– Kuba Ober
Nov 12 at 12:47
Interrupt handling can cause reentrancy, but is hardly the only way of it happening. Recall that on Windows, event processing can invoke IO completion as well, so both Qt and the OS itself may invoke code you never designed to be invoked.
– Kuba Ober
Nov 12 at 12:51
add a comment |
up vote
-1
down vote
up vote
-1
down vote
After reading this article: https://doc.qt.io/archives/qq/qq27-responsive-guis.html
I have added code to my C++ function to process all the events before it starts the heavy process. This way, I empty event queue and the GUI updates automatically showing the progress bar dialog. (a sort of repaint() of all QML objects)
for (int i=0; i<10000; i++)
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
The delay caused by this loop is unnoticeable compared to the 2 seconds of processing time. The 10,000 iterations are needed on Android, on desktop 10 iterations is enough. Using small amount of iterations, will show the dialog not at full opacity, due to fade effects.
After reading this article: https://doc.qt.io/archives/qq/qq27-responsive-guis.html
I have added code to my C++ function to process all the events before it starts the heavy process. This way, I empty event queue and the GUI updates automatically showing the progress bar dialog. (a sort of repaint() of all QML objects)
for (int i=0; i<10000; i++)
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
The delay caused by this loop is unnoticeable compared to the 2 seconds of processing time. The 10,000 iterations are needed on Android, on desktop 10 iterations is enough. Using small amount of iterations, will show the dialog not at full opacity, due to fade effects.
answered Nov 8 at 23:33
Nulik
1,59812148
1,59812148
This seems bad design and not very flexible. Why not use a worker thread and a progress bar? You can disable UI interaction during that time but the UI stays responsive with updates.
– Jan Win
Nov 9 at 9:35
1
TheprocessEvents
call exposes your entire codebase to reentrancy, and I bet that you didn't design your code with reentrancy in mind. Don't do that.
– Kuba Ober
Nov 9 at 16:15
reentrancy is when it is interruped by hadware interrupt (or soft interrupt), here, it is not reentrancy, since I am interrupting it in a safe place. During this interrupt the local stack is not being changed, process objects are not being changed. global vars may be changed, but that's why they are global vars. It is just quick patch for the problem, I will rewrite it in the future with a timer on QML side.
– Nulik
Nov 9 at 18:55
No. Reentrancy means that a function not designed to do so is on the call stack two or more times in a given thread. AndprocessEvents
can end up calling any method in your code that would be callable as a result of event processing, I.e. timers, UI interaction including windows getting closed, communications – heck, you might start doing application-exit cleanup tasks within thatprocessEvents
. And you simply should not block the event loop period. Do your computation asynchronously. It’s amenable to it. Use the concurrent pramework of standard C++ async primitives.
– Kuba Ober
Nov 12 at 12:47
Interrupt handling can cause reentrancy, but is hardly the only way of it happening. Recall that on Windows, event processing can invoke IO completion as well, so both Qt and the OS itself may invoke code you never designed to be invoked.
– Kuba Ober
Nov 12 at 12:51
add a comment |
This seems bad design and not very flexible. Why not use a worker thread and a progress bar? You can disable UI interaction during that time but the UI stays responsive with updates.
– Jan Win
Nov 9 at 9:35
1
TheprocessEvents
call exposes your entire codebase to reentrancy, and I bet that you didn't design your code with reentrancy in mind. Don't do that.
– Kuba Ober
Nov 9 at 16:15
reentrancy is when it is interruped by hadware interrupt (or soft interrupt), here, it is not reentrancy, since I am interrupting it in a safe place. During this interrupt the local stack is not being changed, process objects are not being changed. global vars may be changed, but that's why they are global vars. It is just quick patch for the problem, I will rewrite it in the future with a timer on QML side.
– Nulik
Nov 9 at 18:55
No. Reentrancy means that a function not designed to do so is on the call stack two or more times in a given thread. AndprocessEvents
can end up calling any method in your code that would be callable as a result of event processing, I.e. timers, UI interaction including windows getting closed, communications – heck, you might start doing application-exit cleanup tasks within thatprocessEvents
. And you simply should not block the event loop period. Do your computation asynchronously. It’s amenable to it. Use the concurrent pramework of standard C++ async primitives.
– Kuba Ober
Nov 12 at 12:47
Interrupt handling can cause reentrancy, but is hardly the only way of it happening. Recall that on Windows, event processing can invoke IO completion as well, so both Qt and the OS itself may invoke code you never designed to be invoked.
– Kuba Ober
Nov 12 at 12:51
This seems bad design and not very flexible. Why not use a worker thread and a progress bar? You can disable UI interaction during that time but the UI stays responsive with updates.
– Jan Win
Nov 9 at 9:35
This seems bad design and not very flexible. Why not use a worker thread and a progress bar? You can disable UI interaction during that time but the UI stays responsive with updates.
– Jan Win
Nov 9 at 9:35
1
1
The
processEvents
call exposes your entire codebase to reentrancy, and I bet that you didn't design your code with reentrancy in mind. Don't do that.– Kuba Ober
Nov 9 at 16:15
The
processEvents
call exposes your entire codebase to reentrancy, and I bet that you didn't design your code with reentrancy in mind. Don't do that.– Kuba Ober
Nov 9 at 16:15
reentrancy is when it is interruped by hadware interrupt (or soft interrupt), here, it is not reentrancy, since I am interrupting it in a safe place. During this interrupt the local stack is not being changed, process objects are not being changed. global vars may be changed, but that's why they are global vars. It is just quick patch for the problem, I will rewrite it in the future with a timer on QML side.
– Nulik
Nov 9 at 18:55
reentrancy is when it is interruped by hadware interrupt (or soft interrupt), here, it is not reentrancy, since I am interrupting it in a safe place. During this interrupt the local stack is not being changed, process objects are not being changed. global vars may be changed, but that's why they are global vars. It is just quick patch for the problem, I will rewrite it in the future with a timer on QML side.
– Nulik
Nov 9 at 18:55
No. Reentrancy means that a function not designed to do so is on the call stack two or more times in a given thread. And
processEvents
can end up calling any method in your code that would be callable as a result of event processing, I.e. timers, UI interaction including windows getting closed, communications – heck, you might start doing application-exit cleanup tasks within that processEvents
. And you simply should not block the event loop period. Do your computation asynchronously. It’s amenable to it. Use the concurrent pramework of standard C++ async primitives.– Kuba Ober
Nov 12 at 12:47
No. Reentrancy means that a function not designed to do so is on the call stack two or more times in a given thread. And
processEvents
can end up calling any method in your code that would be callable as a result of event processing, I.e. timers, UI interaction including windows getting closed, communications – heck, you might start doing application-exit cleanup tasks within that processEvents
. And you simply should not block the event loop period. Do your computation asynchronously. It’s amenable to it. Use the concurrent pramework of standard C++ async primitives.– Kuba Ober
Nov 12 at 12:47
Interrupt handling can cause reentrancy, but is hardly the only way of it happening. Recall that on Windows, event processing can invoke IO completion as well, so both Qt and the OS itself may invoke code you never designed to be invoked.
– Kuba Ober
Nov 12 at 12:51
Interrupt handling can cause reentrancy, but is hardly the only way of it happening. Recall that on Windows, event processing can invoke IO completion as well, so both Qt and the OS itself may invoke code you never designed to be invoked.
– Kuba Ober
Nov 12 at 12:51
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53216647%2fexecuting-a-signal-after-event-loop%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do you execute the heavy process in QML or C++?
– eyllanesc
Nov 8 at 21:50
the heavy process is in C++
– Nulik
Nov 8 at 21:50
then you must execute it in a thread
– eyllanesc
Nov 8 at 21:51
hmm, this is a bit complicated, because the user can go to another screen and that's gonna be undefined behaviour... Maybe I can call a timer few milliseconds after button has been pressed?
– Nulik
Nov 8 at 21:55
can I force a "repaint" of the screen somehow, so my "dialog" with progress bar shows before the heavy process?
– Nulik
Nov 8 at 22:00