[SOLVED] QThread



  • Hi,

    when quitting my application I get a message "QThread: Destroyed while thread is still running" for each thread that was fired.
    My code is completely analogous to the example implementation in QThread's documentation
    @
    class Worker : public QObject
    {
    Q_OBJECT

    public slots:
    void doWork() {
    ...
    }
    };

    void MyObject::putWorkerInAThread()
    {
    Worker *worker = new Worker;
    QThread *workerThread = new QThread(this);

     connect(workerThread, SIGNAL(started()), worker, SLOT(doWork()));
     connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
     worker->moveToThread(workerThread);
    
     // Starts an event loop, and emits workerThread->started()
     workerThread->start();
    

    }
    @

    It seems like the signal finished() is never emitted. I also get this message if the function doWork() doesn't do anything...
    What can be the reason for this?



  • You'll have to trigger the finished signal of the QThread yourself, e.g. by connecting a finished signal in your worker to the quit slot of the QThread.
    There is a nice and compact overview in the BlackBerry forums "here":http://supportforums.blackberry.com/t5/Cascades-Development-Knowledge/The-Recommended-Way-to-Use-QThread/ta-p/1803765



  • Try to create a signal that will connect to quit slot of thread.
    That signal will be emitted when 'doWork()' method finish.

    Something like this:

    [code]
    class Worker : public QObject
    {
    Q_OBJECT

    public slots:
    void doWork() {
    ...
    emit close();
    }
    ...
    signals:
    close();
    ...
    [/code]



  • [quote author="Sashko" date="1364419916"]It seems like the signal finished() is never emitted. I also get this message if the function doWork() doesn't do anything...
    What can be the reason for this?[/quote]

    The reason is that you did not derive your own class from QThread and thus you did not re-implement run(). Instead just used the default implementation of QThread::run(). That's okay. It's even the preferred method now. But you need to be aware that the default implementation of QThread::run() will simply run an event loop! So when you start the thread, its started() signal is emitted and calls the doWork() slot of your Worker class. But when that slot is finished, there is no reason for the QThread's default implementation to stop event processing at that point, i.e. the thread will happily continue to run and continue to do event processing! Thus no finished() signal! You will need to make your Worker thread emit some workComplete() signal when it's done and connect that signal to QThread::quit(). This will cause the QThread to exit the event loop and terminate.



  • You are missing two connect statements.
    @
    connect(workerThread, SIGNAL(started()), worker, SLOT(doWork()));
    connect(worker, SIGNAL(finished()), workerThread, SLOT(quit())); // this one was missing
    connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater())); // and this one was missing
    connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
    @



  • Thank you all a lot! Though I cannot try it out at the moment, I'm pretty sure that this will solve the problem :-)

    I also thought about this issue like you discribed in your explanations. But I was mislead by the example in the documentation. I'm very used to the examples in Qt-docs that always simply work. So, maybe one should improve the documentation at this place...

    Thanks a lot again!



  • How do I mark a thread as "solved"? Just edit the original post and put something like [SOLVED] into the subject?



  • yeah just edit your first post.


Log in to reply
 

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