How to add a C++ object into a Qt Thread ?



  • Hi all,
    I have tried reading different discussions about Qt Threads and the ways to implement them which left me completely confused.
    In my case, I have a class StageController which contains all the parameters and methods for controlling a stage. I want to instantiate this class and keep the object into a new thread which runs parallel to the GUI thread. In this way, I can call the object's function whenever I want in the GUI and it implements the function on the parallel thread. But it doesn't seem to work.

    There are apparently two approaches. One would be to subclass QThread and reimplement the run function. But I want to put a whole object and not just one function.
    The other approach(more object-oriented one) is to subclass QObject in your class definition and use the moveToThread() command.
    @
    QThread StageThread;
    stage = new StageController();
    stage->moveToThread(&StageThread);
    StageThread.start();@

    In this way, I get the error saying "QThread:Destroyed while thread is still running". If I use

    @StageThread.wait();@

    as suggested in some forums, then the program hangs.
    The common example of producer and worker threads doesn't look so appealing since I would then need to use Slots and Signals for every method that my class has.

    Can somebody shed some light in this regard ? Thanks in advance :).



  • Don't know where the code is inside the application but most probably you have to create the thread on the heap!



  • I use the code described in "this post":qt-project.org/forums/viewthread/15626/ .

    You can do this:
    @
    QThread *thread = new QThread();
    stage = new StageController();
    stage->moveToThread(thread);
    connect(stage, SIGNAL(destroyed()), thread, SLOT(quit()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
    @



  • [quote author="Luca" date="1333435472"]I use the code described in "this post":qt-project.org/forums/viewthread/15626/ .

    You can do this:
    @
    QThread *thread = new QThread();
    stage = new StageController();
    stage->moveToThread(thread);
    connect(stage, SIGNAL(destroyed()), thread, SLOT(quit()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
    @
    [/quote]

    Now you only need to remember to delete "stage" object when you want...



  • Thanks Lykurg and Luca for your replies and detailed answer. Creating the thread on the heap helped and I did not get that error.
    Of course, now I have to ensure that I kill the stage before killing the thread.

    Thanks guys!!



  • You don't have to delete the thread if you set the connect statements as suggested above. Only delete your stage instance when you're done, the rest will be handled via the connected signals and slots.



  • Yes you are right KA510.. In my code, I hadn't connected the signals and slots earlier as above. So I had to quit the thread after killing the object instance manually. But Luca's connections make life easier definitely :).



  • Be aware that the first article is obsolete as of Qt 4.4, as QThread::run() is in fact no longer pure virtual and the default implementation calls QThread::exec() (as suggested in the article).



  • Note that none of the articles say that you should not subclass QThread. There are still valid reasons to do so in some cases. You just have to understand what it means if you do so, and realize that for a lot of cases, it makes more sense to move a QObject-derived worker object to a vanilla QThread.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.