[SOLVED] Close a Qthread in the middle of it



  • i have a QDialog and inside it's constructor a start a thread. but what if the user closes the dialog before thread is finished ? my solution was to implement closeEvent of the dialog so that i can quit the thread but still my app crashes ;-(

    here is my code:

    @
    MyDialog::MyDialog() :
    ui(new Ui::MyDialog)
    {
    QTimer::singleShot(50, this, SLOT(startThread()));
    }

    void MyDialog::startThread()
    {
    QObject::connect(&thrTest, SIGNAL(started()), &objAnotherClass, SLOT(sampleSlot()));
    QObject::connect(&objAnotherClass, SIGNAL(sampleSlotFinished(int)), this, SLOT(sampleSlotFinished(int)));
    objAnotherClass.moveToThread(&thrTest);
    thrTest.start();
    }

    void MyDialog::sampleSlotFinished(int returnValue)
    {
    .
    .
    .
    // QUIT THREAD
    QObject::disconnect(&objAnotherClass, 0, 0, 0);
    QObject::disconnect(&thrTest, 0, 0, 0);
    thrTest.quit();
    thrTest.exit(0);
    }

    void MyDialog::closeEvent(QCloseEvent *event)
    {
    Q_UNUSED(event);
    if(thrTest.isRunning())
    {
    disconnect(&thrTest, 0, 0, 0);
    disconnect(&objAnotherClass, 0, 0, 0);
    thrTest.quit();
    thrTest.exit(0);
    thrTest.deleteLater();
    objAnotherClass.deleteLater();
    }
    }

    @



  • Think in the closeEvent of the Dialog you need to wait until the QThread is done via:
    @
    while(isFinished() == false)
    @ check. Then do the deletion of them all.
    The problem is that your QThread object resides in the Dialog class. When you do a deleteLater on that one, if will get deleted when the dialog event queue is empty, but then the QThread object might not be ended. This probably causes the crash.



  • thanks for reply.

    i changed close event to below code:

    @
    void MyDialog::closeEvent(QCloseEvent *event)
    {
    Q_UNUSED(event);
    if(thrTest.wait()) // block until thread is finished
    {
    disconnect(&thrTest, 0, 0, 0);
    disconnect(&objAnotherClass, 0, 0, 0);
    thrTest.deleteLater();
    objAnotherClass.deleteLater();
    }
    }
    @
    but the problem is if i wait on that thread! it will also block the main thread(Caller Thread) so application won't respond untill this thread is finished!



  • [quote author="Jeroentje@home" date="1383816067"]Think in the closeEvent of the Dialog you need to wait until the QThread is done via:
    @
    while(isFinished() == false)
    @ check. Then do the deletion of them all.
    The problem is that your QThread object resides in the Dialog class. When you do a deleteLater on that one, if will get deleted when the dialog event queue is empty, but then the QThread object might not be ended. This probably causes the crash. [/quote]

    thanks for reply.

    i changed close event to below code:
    @
    void MyDialog::closeEvent(QCloseEvent *event)
    {
    Q_UNUSED(event);
    if(thrTest.wait()) // block until thread is finished
    {
    disconnect(&thrTest, 0, 0, 0);
    disconnect(&objAnotherClass, 0, 0, 0);
    thrTest.deleteLater();
    objAnotherClass.deleteLater();
    }
    }
    @

    but the problem is if i wait on that thread! it will also block the main thread(Caller Thread) so application won’t respond untill this thread is finished!



  • Have a look at "this thread":http://qt-project.org/forums/viewthread/34537/ , the problem is similar to yours.



  • [quote author="KA51O" date="1383818721"]Have a look at "this thread":http://qt-project.org/forums/viewthread/34537/ , the problem is similar to yours.[/quote]

    thanks for the link.
    by reading that post i came to the idea of using boolean data members and always checking that members inside thread, sounds good!
    i will happily accept any other workarounds.



  • Chopping the worker object (that runs in the QThread) is a good idea and handling timing in the worker object. Then add a slot for the "StopObject" thread and your done. That's about the easiest way, so yes, checking boolean variables is not a problem. Or in the "stop" slot, close the file or other thing the thead has open. Delete all allocated memory and set this->deleteLater() and emit the finished signal to have the QThread that controls the object be closed and removed.
    That should work fine.



  • Thank you all.
    i also encourage people with the same problem have a look at these two links which perfectly and simply cover how to use Qthread
    "1st":https://fabienpn.wordpress.com/2013/05/01/qt-thread-simple-and-stable-with-sources/

    "2nd":https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/


Log in to reply
 

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