Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
Hi, On Sunday 07 August 2016 10:06:54 Thiago Macieira wrote: > On domingo, 7 de agosto de 2016 10:17:44 PDT André Somers wrote: > > > Yet, I don't see where the problem is. QDialog::exec() displays a > > > modal > > > dialog. It is not possible to click again on the menu or button that > > > displayed the dialog in the first place. It effectively breaks > > > recursive > > > looping, right? > > > > Wrong. There are many sources of events, and only the ones related to > > user input are blocked this way. > > Indeed. Think of your sockets, that are still receiving data and that is > being processed. Are you sure that your dialog wasn't created as a > response to some data being processed earlier? > > Think also of all the timers that will time out. Let me weigh in at this point: yes, it is true - nested event loops make it very easy to shoot yourself in the foot. Sorry, you are using C++, if you wanted it safe you would bake bread. I use them all the time because they make simple algorithms understandable - event based constructs, even using lambdas, make them horribly hard to understand. I even wrote a few such methods for my own code. Here's the choice: a) avoid exec() at all costs and suffer unreadable code and a lot of the problems described below simply get hidden in a forest of less readable code b) follow a few simple rules instead: - avoid direct delete on QObjects - use deleteLater instead (it is delayed for the main event loop) - use high-level methods instead of deletes: e.g. tell a window to close itself and set it up for automatic cleanup instead of deleting it directly - try to communicate via signals and set the connections up when you create the receiver object - Qt will clean the connections up when the receiver is deleted - if you absolutely and positively cannot avoid using a pointer - use QPointer and check it before you call a method - enable your code to deal with disappearing objects - i.e. let a child object tell its parent that it is gone and stop any actions that depend on it when you receive this signal (otherwise you risk endless waiting) - when you write code that can take a while: think about everything that could conceivably happen in between and prepare the program for "stuff happening" - i.e. disappearing objects, more events coming in, things queuing up, the user losing patience and clicking "Exit", etc. Qt make it very easy for you to write readable code - I refuse to compromise this out of paranoia. Konrad signature.asc Description: This is a digitally signed message part. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On domingo, 7 de agosto de 2016 10:17:44 PDT André Somers wrote: > > Yet, I don't see where the problem is. QDialog::exec() displays a modal > > dialog. It is not possible to click again on the menu or button that > > displayed the dialog in the first place. It effectively breaks recursive > > looping, right? > Wrong. There are many sources of events, and only the ones related to user > input are blocked this way. Indeed. Think of your sockets, that are still receiving data and that is being processed. Are you sure that your dialog wasn't created as a response to some data being processed earlier? Think also of all the timers that will time out. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
Verstuurd vanaf mijn iPhone > Op 7 aug. 2016 om 09:12 heeft Frederic Marchal >het volgende geschreven: > > On Thursday 04 August 2016 11:20:58 Thiago Macieira wrote: > > On quinta-feira, 4 de agosto de 2016 10:32:26 PDT John Weeks wrote: > > > > On Aug 4, 2016, at 10:04 AM, Thiago Macieira > > > > wrote: > > > > > > > > Starting an event loop from inside another event loop. > > > > > > > > exec() → some slot or event handler → exec() > > > > > > It would also seem to cover any use of QDialog::exec() in the main thread, > > > and QDialog can be used only in the main thread. > > > > Correct. Don't use exec(). Call show() it and return to the existing > > mainloop. > > That's very restrictive! > > It is common (at least to me) to call QFileDialog::getOpenFileName() when the > user clicks on the "Open" menu and then use the returned file name to carry > on the open action. QFileDialog::getOpenFileName() does call QDialog::exec(). > According to you, it must be avoided like the plague… It means it renders > similar QFileDialog static methods useless. > > Yet, I don't see where the problem is. QDialog::exec() displays a modal > dialog. It is not possible to click again on the menu or button that > displayed the dialog in the first place. It effectively breaks recursive > looping, right? > Wrong. There are many sources of events, and only the ones related to user input are blocked this way. André > Frederic > > ___ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On Thursday 04 August 2016 11:20:58 Thiago Macieira wrote: > On quinta-feira, 4 de agosto de 2016 10:32:26 PDT John Weeks wrote: > > > On Aug 4, 2016, at 10:04 AM, Thiago Macieira> > > wrote: > > > > > > Starting an event loop from inside another event loop. > > > > > > exec() → some slot or event handler → exec() > > > > It would also seem to cover any use of QDialog::exec() in the main thread, > > and QDialog can be used only in the main thread. > > Correct. Don't use exec(). Call show() it and return to the existing > mainloop. That's very restrictive! It is common (at least to me) to call QFileDialog::getOpenFileName() when the user clicks on the "Open" menu and then use the returned file name to carry on the open action. QFileDialog::getOpenFileName() does call QDialog::exec(). According to you, it must be avoided like the plague… It means it renders similar QFileDialog static methods useless. Yet, I don't see where the problem is. QDialog::exec() displays a modal dialog. It is not possible to click again on the menu or button that displayed the dialog in the first place. It effectively breaks recursive looping, right? Frederic ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On quinta-feira, 4 de agosto de 2016 10:32:26 PDT John Weeks wrote: > > On Aug 4, 2016, at 10:04 AM, Thiago Macieira> > wrote: > > > > Starting an event loop from inside another event loop. > > > > exec() → some slot or event handler → exec() > > OK, so that would cover any use of QEventLoop::exec() in the main thread. Correct, unless you did it in the main() function before or instead of QCoreApplication::main(). > It would also seem to cover any use of QDialog::exec() in the main thread, > and QDialog can be used only in the main thread. Correct. Don't use exec(). Call show() it and return to the existing mainloop. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
> On Aug 4, 2016, at 10:04 AM, Thiago Macieira> wrote: > > Starting an event loop from inside another event loop. > > exec() → some slot or event handler → exec() OK, so that would cover any use of QEventLoop::exec() in the main thread. It would also seem to cover any use of QDialog::exec() in the main thread, and QDialog can be used only in the main thread. -John Weeks ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On quinta-feira, 4 de agosto de 2016 09:25:21 PDT John Weeks wrote: > At the risk of displaying my ignorance... > > Having followed this thread with great interest, I have come to the > conclusion that perhaps I'm not really certain what you mean by "nested". > Any chance of an example? Starting an event loop from inside another event loop. exec() → some slot or event handler → exec() -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
At the risk of displaying my ignorance... Having followed this thread with great interest, I have come to the conclusion that perhaps I'm not really certain what you mean by "nested". Any chance of an example? > On Aug 3, 2016, at 10:31 PM, Thiago Macieira> wrote: > > I disagree. You should try to split. Lambdas might help. > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > ___ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest Lambdas have always seemed like a great way to write large blocks of obscure code, but it seems like I'm missing something. Another example? -John ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On quinta-feira, 4 de agosto de 2016 04:21:44 PDT Uwe Rathmann wrote: > Having to write this code without nested loops ( f.e. QDialog::exec() ) > leads to 3 method ... > > - before askForOption > - between askForOption and doYouReallyWantTo > - after doYouReallyWantTo > > ... where you always have the problem to transfer the variables from the > stack ( here option ). > > Once your code ends up in sequences of between-GUI-interactions methods > you will have way more problems, than what nested event loops might be. > > So yes nested loops might be a problem, but not using them is IMHO the > wrong consequence. I disagree. You should try to split. Lambdas might help. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On Wed, 03 Aug 2016 13:41:51 -0700, Thiago Macieira wrote: > It's still a source of errors because the nesting counter can be > incremented in different ways, depending on what triggered the event. So > the recommendation remains: avoid nesting like the plague. void doIt() { ... int option = askForOption(); ... if ( doYouReallyWantTo( option ) ) { ... } } Having to write this code without nested loops ( f.e. QDialog::exec() ) leads to 3 method ... - before askForOption - between askForOption and doYouReallyWantTo - after doYouReallyWantTo ... where you always have the problem to transfer the variables from the stack ( here option ). Once your code ends up in sequences of between-GUI-interactions methods you will have way more problems, than what nested event loops might be. So yes nested loops might be a problem, but not using them is IMHO the wrong consequence. Uwe ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On quarta-feira, 3 de agosto de 2016 22:25:32 PDT Konstantin Shegunov wrote: > On Wed, Aug 3, 2016 at 8:58 PM, Thiago Macieira> > wrote: > > On quarta-feira, 3 de agosto de 2016 11:22:36 PDT Jorge Fierro wrote: > > > - If QEventLoop::exec() spins the main loop then any event at all can > > > be generated. Is this why one must use it very carefully to avoid > > > reentrancy issues? > > > > Yes. Avoid nesting event loops like the plague. > > With, I believe, the important exception being the deferred deletion > events, which are processed only be the last (main) event loop. Correct, the deletion events are only processed by an event loop of the same equally or less nested than when the event was posted. That exists because a lot of code depends on deleteLater() being much later than what was happening. It's still a source of errors because the nesting counter can be incremented in different ways, depending on what triggered the event. So the recommendation remains: avoid nesting like the plague. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On Wed, Aug 3, 2016 at 8:58 PM, Thiago Macieirawrote: > On quarta-feira, 3 de agosto de 2016 11:22:36 PDT Jorge Fierro wrote: > > - If QEventLoop::exec() spins the main loop then any event at all can > > be generated. Is this why one must use it very carefully to avoid > > reentrancy issues? > > Yes. Avoid nesting event loops like the plague. > With, I believe, the important exception being the deferred deletion events, which are processed only be the last (main) event loop. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
> Sent: Wednesday, August 03, 2016 at 1:22 PM > From: "Jorge Fierro" <jo...@jorgefierro.com> > To: interest@qt-project.org > Subject: [Interest] Relationship between a QEventLoop and > QCoreApplication::exec(). > > Hi. I've been reading through the documentation and mailing list > archives and I haven't found an authoritative and/or conclusive answer to > the following question: > > What exactly is the relationship between an event loop entered by > calling QEventLoop::exec() and *the* main event loop (the one running > when you can QCoreApplication::exec())? > > There are a number of related questions: > > - Does QEventLoop::exec() enter *the* main event loop? Or, > - Does QEventLoop::exec() enter a different event loop independent > from QCoreApplication::exec()? > - Can QEventLoop::exec() be called outside QCoreApplication::exec() > (i.e., in a call stack that didn't originate from > QCoreApplication::exec())? > - If QEventLoop::exec() spins the main loop then any event at all can > be generated. Is this why one must use it very carefully to avoid > reentrancy issues? As far as I know QCoreApplication::exec() does call QEventLoop::exec(). A thread can have a event loop, and cross-thread signal/slot communication is done via messages in each thread's event loop. A thread may have more than one event loop. (I think I used this in the past to handle some modal dialog issues. I think while the second event loop is running that the first is unresponsive.) HTH. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().
On quarta-feira, 3 de agosto de 2016 11:22:36 PDT Jorge Fierro wrote: > What exactly is the relationship between an event loop entered by > calling QEventLoop::exec() and *the* main event loop (the one running > when you can QCoreApplication::exec())? Both functions as well as QThread::exec() are windows into the actual event dispatcher that runs behind the scenes. All three control the QAbstractEventDispatcher that either QCoreApplication or QThread creates. I think these two links answer your question best: https://code.woboq.org/qt5/qtbase/src/corelib/kernel/ qcoreapplication.cpp.html#_ZN16QCoreApplication4execEv (line 1258) https://code.woboq.org/qt5/qtbase/src/corelib/thread/ qthread.cpp.html#_ZN7QThread4execEv (line 506) As you can see, both QCoreApplication::exec or QThread::exec create a QEventLoop and call exec on it. The same is also true, for that matter, for QDialog::exec. > There are a number of related questions: > > - Does QEventLoop::exec() enter *the* main event loop? Or, > - Does QEventLoop::exec() enter a different event loop independent > from QCoreApplication::exec()? There's only one event dispatcher per thread. > - Can QEventLoop::exec() be called outside QCoreApplication::exec() > (i.e., in a call stack that didn't originate from QCoreApplication::exec())? Sure. You could even use QEventLoop::exec() in place of QCoreApplication::exec() in your main function or QThread::exec() in your run function. The two are very similar, but not identical. QCoreApplication's loop emits aboutToQuit and its descendant classes react to the last window closing, while QEventLoop does not. > - If QEventLoop::exec() spins the main loop then any event at all can > be generated. Is this why one must use it very carefully to avoid > reentrancy issues? Yes. Avoid nesting event loops like the plague. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
[Interest] Relationship between a QEventLoop and QCoreApplication::exec().
Hi. I've been reading through the documentation and mailing list archives and I haven't found an authoritative and/or conclusive answer to the following question: What exactly is the relationship between an event loop entered by calling QEventLoop::exec() and *the* main event loop (the one running when you can QCoreApplication::exec())? There are a number of related questions: - Does QEventLoop::exec() enter *the* main event loop? Or, - Does QEventLoop::exec() enter a different event loop independent from QCoreApplication::exec()? - Can QEventLoop::exec() be called outside QCoreApplication::exec() (i.e., in a call stack that didn't originate from QCoreApplication::exec())? - If QEventLoop::exec() spins the main loop then any event at all can be generated. Is this why one must use it very carefully to avoid reentrancy issues? Thanks. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest