Solved QThread: Destroyed while thread is still running
-
When I use Qt multithreading, I encounter this problem: "QThread: Destroyed while thread is still running".
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.
-
@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. -
@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. -
@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.