Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QThread: Destroyed while thread is still running



  • When I use Qt multithreading, I encounter this problem: "QThread: Destroyed while thread is still running".
    QThread.png

    The MainWindow.h :

    class MainWindow : public QMainWindow 
    {
    .....
    private:
        QThread TerraThread;
        TerraWorker* terraWorker = NULL;
    }
    

    The MainWindow.cpp :

    MainWindow::MainWindow()
    {
        terraWorker = new TerraWorker;
        terraWorker->moveToThread(&TerraThread);
        connect(terraWorker, &QObject::destroyed, &TerraThread, &QThread::quit);
        connect(&TerraThread, &QThread::finished, terraWorker, &QObject::deleteLater);
        connect(&TerraThread, &QThread::started, terraWorker, &TerraWorker::init);
        TerraThread.start();
    }
    

    The terraWoker.h :

    #pragma once
    #include <QObject>
    #include "terrasinkevent.h"
    
    class TerraWorker :   public QObject
    {
    	Q_OBJECT
    
    public:
    	//TerraWorker();
    	//~TerraWorker();
    
    public slots:
    	void init();
    private:
    
    signals:
    
    private:
    	TerraSinkEvent* m_pTerraSink = NULL;
    	ISGWorld71Ptr m_pISGWorld = NULL;
    };
    
    

    The terraWorker.cpp :

    #include "terraworker.h"
    #include <QDebug>
    #include <QtCore/QThread> 
    
     void TerraWorker::init()
     {
         CoInitialize(NULL);
         
         //TerraSinkEvent* m_pTerraSink = new TerraSinkEvent();
         //ISGWorld71Ptr m_pISGWorld = NULL;
         m_pTerraSink = new TerraSinkEvent();
         m_pISGWorld.CreateInstance(CLSID_SGWorld71);
         if (m_pISGWorld != NULL)
         {
             HRESULT hr = m_pTerraSink->DispEventAdvise(m_pISGWorld);
             if (FAILED(hr))
             {
                 qDebug() << "DispEventAdvise Failed...";
             }
         }
         m_pISGWorld->Project->Open("C:\\Skyline\\TerraExplorer\\Beijing-15\\Beijing_15.FLY", FALSE, "", "");
         IPosition71Ptr pIPosition71 = m_pISGWorld->Creator->CreatePosition(116.2, 40.4, 1500, AltitudeTypeCode::ATC_TERRAIN_RELATIVE, 0, 0, 0, 0);
         m_pISGWorld->Navigate->FlyTo(_variant_t((IDispatch*)pIPosition71), ActionCode::AC_FLYTO);
         qDebug() << "TerraWorker Thread: " << QThread::currentThreadId();
     }
    

    The terrasinkevent.h :

    #pragma once
    
    #include <atlbase.h>
    #include <atlcom.h>
    #include <QDebug>
    
    #include "terraexplorerx.tlh"
    
    static _ATL_FUNC_INFO info = { CC_STDCALL, VT_EMPTY, 1, {VT_BOOL} };
    static _ATL_FUNC_INFO onLButtonDownInfo = { CC_STDCALL, VT_EMPTY, 3, {VT_I4, VT_I4, VT_I4 } };
    static _ATL_FUNC_INFO infoEmpty = { CC_STDCALL, VT_EMPTY, 0, {} };
    
    
        class  TerraSinkEvent : public IDispEventSimpleImpl
                    <1, TerraSinkEvent, &DIID__ISGWorld71Events>
    {
    public:
        TerraSinkEvent();
    
        ~TerraSinkEvent();
    
        STDMETHODIMP OnLButtonDown(long Flags, int X, int Y, VARIANT_BOOL* pbHandled)
        {
            qDebug() << "Jump into OnLButtonDown...";
            return S_OK;
        }
    
        STDMETHODIMP OnLoadFinished(VARIANT_BOOL bSuccess)
        {
            return S_OK;
        }
    
    
        BEGIN_SINK_MAP(TerraSinkEvent)
            SINK_ENTRY_INFO(1, DIID__ISGWorld71Events, 9, OnLButtonDown, &onLButtonDownInfo)
        END_SINK_MAP()
    
    };
    

    The * terrasinkevent.cpp* :

    #include "terrasinkevent.h"
    
    TerraSinkEvent::TerraSinkEvent()
    {
    
     }
    
    TerraSinkEvent::  ~TerraSinkEvent()
    {
     
    }
    
    

    I think I use the QThread in right way, but, why it arises "QThread: Destroyed while thread is still running", when I quit the "MainWindow"?

    When I comment these lines in MainWindow.cpp :

        //terraWorker->moveToThread(&TerraThread);
        //connect(terraWorker, &QObject::destroyed, &TerraThread, &QThread::quit);
        //connect(&TerraThread, &QThread::finished, terraWorker, &QObject::deleteLater);
        //connect(&TerraThread, &QThread::started, terraWorker, &TerraWorker::init);
        //TerraThread.start();
    

    And use :

        terraWorker = new TerraWorker;
        terraWorker->init();
    

    This doesn't arise this error, when I quit MainWindow.


  • Moderators

    @Wang-xiaohu said in QThread: Destroyed while thread is still running:

    why it arises "QThread: Destroyed while thread is still running
    ", when I quit the "MainWindow"?

    Because you destroyed the QThread object when the thread was still running.

    You must wait until the thread stops. Call QThread::wait() in your MainWindow's destructor.


  • Moderators

    @Wang-xiaohu said in QThread: Destroyed while thread is still running:

    why it arises "QThread: Destroyed while thread is still running
    ", when I quit the "MainWindow"?

    Because you destroyed the QThread object when the thread was still running.

    You must wait until the thread stops. Call QThread::wait() in your MainWindow's destructor.



  • thank you, I'll have a try.
    I thought it would be OK to use QThread::quit() function.


  • Moderators

    @Wang-xiaohu said in QThread: Destroyed while thread is still running:

    I thought it would be OK to use QThread::quit() function.

    QThread::quit() causes the thread to begin shutting down.

    QThread::wait() waits for the thread to finish shutting down.


Log in to reply