Details
-
Suggestion
-
Resolution: Done
-
P4: Low
-
None
-
4.8.0
-
None
Description
Qt 4.8 and later documentation states, that the "good" practice is using QObject::moveToThread rather than QThread subclassing. Someone somewhere reinvented this wheel and all are very happy. OK, what's about such code snippet:
#include <QCoreApplication> #include <QString> #include <QTimer> #include <QThread> #include <cstdio> class HiMyThreadIs: public QObject { Q_OBJECT public: HiMyThreadIs(const QString& name, QObject* parent=0): QObject(parent), _name(name) { QTimer* timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(report())); timer->setSingleShot(false); timer->start(2000); } public slots: void report() { QString s = QString("[%1] Hi, my thread is %2\n") // yes, I like it! .arg(_name) .arg((unsigned)(QThread::currentThread())); std::fwrite(s.toAscii().constData(), 1, s.toAscii().size(), stderr); } private: QString _name; }; class Parent: public QObject { Q_OBJECT public: Parent(const QString& name, QObject* parent=0): QObject(parent), _orphan(name) {} private: HiMyThreadIs _orphan; }; class BadPracticeThread: public QThread { Q_OBJECT public: BadPracticeThread(QObject* parent=0): QThread(parent) {} virtual void run() { Parent parent("bad practice"); exec(); } }; int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); HiMyThreadIs control_instance("control instance"); QThread good_practice_thread; BadPracticeThread bad_practice_thread; (new Parent("good practice"))->moveToThread(&good_practice_thread); good_practice_thread.start(); bad_practice_thread.start(); return app.exec(); } #include "main.moc"
The output is as expected:
[control instance] Hi, my thread is 154473584 [good practice] Hi, my thread is 154473584 [bad practice] Hi, my thread is 3218021664 [control instance] Hi, my thread is 154473584 [good practice] Hi, my thread is 154473584 [bad practice] Hi, my thread is 3218021664 ^C
You can see, that the "orphan" instance still lives in the same thread, as the "control" instance (i.e. in the main thread) when using QObject::moveToThread. In my home opinion, it's worth noting such a gotcha in the Qt documentation.