Discussion:
[Interest] Event handling for QObjects created before QApplication
Dmitrii Volosnykh
2014-09-22 00:24:21 UTC
Permalink
Threads and QObjects
<http://qt-project.org/doc/qt-5/threads-qobject.html> tutorial
Note that for QObjects that are created before QApplication,
QObject::thread() returns zero. This means that the main thread will only
handle posted events for these objects; other event processing is not done
at all for objects with no thread.
Could someone elaborate on this, please? The most confusing part is "main
thread will only handle posted events for these objects".

Thanks in advance.

Dmitrii.
Thiago Macieira
2014-09-22 00:46:34 UTC
Permalink
Post by Dmitrii Volosnykh
Threads and QObjects
<http://qt-project.org/doc/qt-5/threads-qobject.html> tutorial
Note that for QObjects that are created before QApplication,
QObject::thread() returns zero. This means that the main thread will only
handle posted events for these objects; other event processing is not done
at all for objects with no thread.
Could someone elaborate on this, please? The most confusing part is "main
thread will only handle posted events for these objects".
Qt is not supported before the creation of QCoreApplication. Your use-case is
not supported, so no answer is necessary.

Just don't do it.

Note: the doc is wrong.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Till Oliver Knoll
2014-09-22 08:11:01 UTC
Permalink
Post by Thiago Macieira
Post by Dmitrii Volosnykh
Threads and QObjects
<http://qt-project.org/doc/qt-5/threads-qobject.html> tutorial
Note that for QObjects that are created before QApplication,
QObject::thread() returns zero. This means that the main thread will only
handle posted events for these objects; other event processing is not done
at all for objects with no thread.
Could someone elaborate on this, please? The most confusing part is "main
thread will only handle posted events for these objects".
Qt is not supported before the creation of QCoreApplication. Your use-case is
not supported, so no answer is necessary.
Just don't do it.
Note: the doc is wrong.
It is always a good idea - if not even a hard pre-condition for most or even all QObject based classes - to first create a Q(Core|Gui)Application instance before anything else.

Besides that, I understand "This means that the main thread will only handle posted events for these objects" as "events directly sent (posted) with that specific QObject as target (in contrast to other events such as system events with no particular QObject as target, e.g. keyboard or mouse events).

So the doc writer must have had either QCoreApplication::postEvent or sendEvent in mind (which both let you specify the QObject receiver). However the former requires the main event loop running, which is not the case when you have not yet created a QCoreApplication instance - and we're back at the start.

So in theory it could mean that (only) events sent by QCoreApplication::sendEvent are getting through to your QObject, even without a QCoreApplication instance being around.

In practise I'd always follow Thiago's advice.

I agree that the doc should get some review in either case.

Cheers,
Oliver
Thiago Macieira
2014-09-22 14:46:48 UTC
Permalink
Post by Till Oliver Knoll
So in theory it could mean that (only) events sent by
QCoreApplication::sendEvent are getting through to your QObject, even
without a QCoreApplication instance being around.
Not even sendEvent:

inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
{ if (event) event->spont = false; return self ? self-
Post by Till Oliver Knoll
notifyInternal(receiver, event) : false; }
Note how sendEvent uses the self pointer.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Hamish Moffatt
2014-09-24 01:20:39 UTC
Permalink
Post by Thiago Macieira
Post by Dmitrii Volosnykh
Threads and QObjects
<http://qt-project.org/doc/qt-5/threads-qobject.html> tutorial
Note that for QObjects that are created before QApplication,
QObject::thread() returns zero. This means that the main thread will only
handle posted events for these objects; other event processing is not done
at all for objects with no thread.
Could someone elaborate on this, please? The most confusing part is "main
thread will only handle posted events for these objects".
Qt is not supported before the creation of QCoreApplication. Your use-case is
not supported, so no answer is necessary.
Just don't do it.
Note: the doc is wrong.
Does that mean static objects are not supported either?

We have lots of const QStrings in our (Qt4) application, and some static
(non-const) QLists. But none of these are QObjects and I don't think we
have any static QObjects.


Hamish
Rainer Wiesenfarth
2014-09-24 04:07:45 UTC
Permalink
Post by Hamish Moffatt
Does that mean static objects are not supported either?
I would assume so, yes, as long as you think of static *QObjects*. All
non-QOject derived classes should also be usable for static instances.

But I would be careful with "complex" classes which might have QObject
derived members - although I can't think of one at the moment.

Best Regards / Mit freundlichen Grüßen
Rainer Wiesenfarth
--
Software Engineer | Trimble Imaging Division
Rotebühlstraße 81 | 70178 Stuttgart | Germany
Office +49 711 22881 0 | Fax +49 711 22881 11
http://www.trimble.com/imaging/ | http://www.inpho.de/

Trimble Germany GmbH, Am Prime Parc 11, 65479 Raunheim
Eingetragen beim Amtsgericht Darmstadt unter HRB 83893,
Geschäftsführer: Dr. Frank Heimberg, Hans-Jürgen Gebauer
Thiago Macieira
2014-09-24 15:19:08 UTC
Permalink
Post by Hamish Moffatt
Post by Thiago Macieira
Qt is not supported before the creation of QCoreApplication. Your use-case
is not supported, so no answer is necessary.
Just don't do it.
Note: the doc is wrong.
Does that mean static objects are not supported either?
Not supported, but mostly they work. We will also fix bugs in uses that
reasonably could happen in main() while parsing the command-line and other
set-up procedures before QCoreApplication gets created.

Just be careful because some things will not work. For example,
QString::fromLocal8Bit doesn't work before QCoreApplication.
Post by Hamish Moffatt
We have lots of const QStrings in our (Qt4) application, and some static
(non-const) QLists. But none of these are QObjects and I don't think we
have any static QObjects.
static QObjects are not supported at all. Any application that has those will
get rejected as a testcase on input for a Qt bug report.

The first QObject you should create is QCoreApplication.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Alan Ezust
2014-10-05 15:50:11 UTC
Permalink
Here are my suggested changes to the threads.qdoc. What do you think?

diff --git a/doc/src/frameworks-technologies/threads.qdoc
b/doc/src/frameworks-technologies/threads.qdoc
index 5e92425..b5136fe 100644
--- a/doc/src/frameworks-technologies/threads.qdoc
+++ b/doc/src/frameworks-technologies/threads.qdoc
@@ -632,13 +632,23 @@
event loop. The thread in which a QObject lives is available using
QObject::thread().

- Note that for QObjects that are created before QApplication,
- QObject::thread() returns zero. This means that the main thread
- will only handle posted events for these objects; other event
- processing is not done at all for objects with no thread. Use the
- QObject::moveToThread() function to change the thread affinity for
- an object and its children (the object cannot be moved if it has a
- parent).
+ Note that for QObjects that are created before the QApplication,
+ QObject::thread() returns zero. This means that the main thread will
+ not handle events for these objects. Event processing is not done at
+ all for objects with no thread.
+
+ The above paragraph is for academic interest only. In general,
+ creating QObjects before the QApplication is not supported
+ and can lead to weird crashes on exit, depending on the platform.
+ This means static instances of QObject are also not supported. A
+ properly structured single or multi-threaded application should make
+ the QApplication be the last QObject to be destroyed before exiting.
+
+ The QObject::moveToThread() function can be used to change the
+ thread affinity for a QObject and its children (the object cannot be
+ moved if it has a parent). Unfortunately, QObject::moveToThread()
+ does not work properly for complex QObjects with sub-QObjects, so it
+ is better to create these in the actual thread that uses them.

Calling \c delete on a QObject from a thread other than the one
that \e owns the object (or accessing the object in other ways) is
Post by Thiago Macieira
Post by Dmitrii Volosnykh
Threads and QObjects
<http://qt-project.org/doc/qt-5/threads-qobject.html> tutorial
Note that for QObjects that are created before QApplication,
QObject::thread() returns zero. This means that the main thread will
only
Post by Dmitrii Volosnykh
handle posted events for these objects; other event processing is not
done
Post by Dmitrii Volosnykh
at all for objects with no thread.
Could someone elaborate on this, please? The most confusing part is "main
thread will only handle posted events for these objects".
Qt is not supported before the creation of QCoreApplication. Your use-case is
not supported, so no answer is necessary.
Just don't do it.
Note: the doc is wrong.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Thiago Macieira
2014-10-05 20:22:57 UTC
Permalink
Post by Alan Ezust
Here are my suggested changes to the threads.qdoc. What do you think?
diff --git a/doc/src/frameworks-technologies/threads.qdoc
b/doc/src/frameworks-technologies/threads.qdoc
index 5e92425..b5136fe 100644
--- a/doc/src/frameworks-technologies/threads.qdoc
+++ b/doc/src/frameworks-technologies/threads.qdoc
@@ -632,13 +632,23 @@
event loop. The thread in which a QObject lives is available using
QObject::thread().
- Note that for QObjects that are created before QApplication,
- QObject::thread() returns zero. This means that the main thread
- will only handle posted events for these objects; other event
- processing is not done at all for objects with no thread. Use the
- QObject::moveToThread() function to change the thread affinity for
- an object and its children (the object cannot be moved if it has a
- parent).
+ Note that for QObjects that are created before the QApplication,
+ QObject::thread() returns zero. This means that the main thread will
+ not handle events for these objects. Event processing is not done at
+ all for objects with no thread.
+
+ The above paragraph is for academic interest only. In general,
+ creating QObjects before the QApplication is not supported
+ and can lead to weird crashes on exit, depending on the platform.
+ This means static instances of QObject are also not supported. A
+ properly structured single or multi-threaded application should make
+ the QApplication be the last QObject to be destroyed before exiting.
+
+ The QObject::moveToThread() function can be used to change the
+ thread affinity for a QObject and its children (the object cannot be
+ moved if it has a parent). Unfortunately, QObject::moveToThread()
+ does not work properly for complex QObjects with sub-QObjects, so it
+ is better to create these in the actual thread that uses them.
Looks good, except for the last sentence (starting at "Unfortunately"). Please
remove that sentence and submit to codereview.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Alan Ezust
2014-10-06 17:01:02 UTC
Permalink
Done. https://codereview.qt-project.org/96416
Post by Thiago Macieira
Post by Alan Ezust
Here are my suggested changes to the threads.qdoc. What do you think?
[....]
Looks good, except for the last sentence (starting at "Unfortunately"). Please
remove that sentence and submit to codereview.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Dmitrii Volosnykh
2014-09-22 08:56:56 UTC
Permalink
Thank you for your answers and recommendations. I never create QObjects
before QCoreApplication, so don't worry. Just was re-reading docs and was
confused by that part, especially be the word "posted" since
QCoreApplication::postEvent() supposed to put event in the queue which is
not handled.
Threads and QObjects <http://qt-project.org/doc/qt-5/threads-qobject.html> tutorial
Note that for QObjects that are created before QApplication,
QObject::thread() returns zero. This means that the main thread will only
handle posted events for these objects; other event processing is not done
at all for objects with no thread.
Could someone elaborate on this, please? The most confusing part is "main
thread will only handle posted events for these objects".
Thanks in advance.
Dmitrii.
Loading...