C++ 如何使用辅助线程正确退出Qt应用程序?

C++ 如何使用辅助线程正确退出Qt应用程序?,c++,qt,C++,Qt,退出Qt应用程序的最佳做法是什么?我是这样做的 int main(int argc, char *argv[]) { MyApplication app(argc, argv); return myApp.exec(); } MyApplication::MyApplication( int& argc, char** argv ) : QApplication( argc, argv ) { m_window= new MyWidget();

退出Qt应用程序的最佳做法是什么?我是这样做的

int main(int argc, char *argv[])
{
    MyApplication app(argc, argv);
    return myApp.exec();
}

MyApplication::MyApplication( int& argc, char** argv ) : 
    QApplication( argc, argv )
{
    m_window= new MyWidget();
    m_worker= new MyWorker();
    m_threadWorker = new QThread;
    m_worker->moveToThread(m_threadWorker);

    connect(this, SIGNAL(aboutToQuit()),m_worker,SLOT(quit()));

    connect(m_worker, SIGNAL(finished()), m_worker, SLOT(deleteLater()));
    connect(m_worker, SIGNAL(finished()), m_threadWorker, SLOT(quit()));
    connect(m_threadWorker, SIGNAL(finished()), m_threadWorker, SLOT(deleteLater()));

    m_threadWorker->start();
    m_window->show();
}

MyApplication::~MyApplication()
{
    m_window->deleteLater();
    qDebug()<<"MyApplication::~MyApplication()";
}

MyWorker::quit()
{
    //longer ending operations freeing resources
    emit finished();
    qDebug() << "MyWorker::quit() emit finished()";
}

MyWorker::~MyWorker()
{
    qDebug() << "MyWorker::~MyWorker()";
}
intmain(intargc,char*argv[])
{
MyApplication应用程序(argc、argv);
返回myApp.exec();
}
MyApplication::MyApplication(int&argc,char**argv):
QApplication(argc、argv)
{
m_window=new MyWidget();
m_worker=新的MyWorker();
m_threadWorker=新的QThread;
m_-worker->moveToThread(m_-threadWorker);
连接(此,信号(aboutToQuit()),m_工作,插槽(quit());
连接(m_-worker,信号(finished()),m_-worker,插槽(deleteLater());
连接(m_-worker、信号(finished())、m_-threadWorker、插槽(quit());
连接(m_threadWorker,信号(finished()),m_threadWorker,插槽(deleteLater());
m_threadWorker->start();
m_窗口->显示();
}
MyApplication::~MyApplication()
{
m_window->deleteLater();

qDebug()问题在于
aboutToQuit
不会等待工作进程完成。您必须显式地等待它完成:

connect(this, &MyApplication::aboutToQuit,
        this, &MyApplication::stopWorker);

// also, change up your connects a little to make shure everything gets deleted properly
connect(m_worker, &MyWorker::finished, 
        m_threadWorker, &QThread::quit,
        Qt::DirectConnection); //direct connection is needed, because you are blocking the main thread by waiting
connect(m_threadWorker, &QThread::finished,
        m_worker, &MyWorker::deleteLater);


MyApplication::stopWorker() {
    QMetaObject::invokeMethod(m_worker, "quit");
    m_threadWorker->wait();
    m_threadWorker->deleteLater();
}
但是,这将在等待工作程序完成时“冻结”您的应用程序。如果您想在等待过程中保持响应,请在
MyApplication::stopWorker
中使用本地
QEventLoop
,并将其用作:

MyApplication::stopWorker() {
    QEventLoop stopLoop;
    connect(m_threadWorker, &QThread::finished,
            &stopLoop, &QEventLoop::quit);
    QMetaObject::invokeMethod(m_worker, "quit");
    stopLoop.exec();
    m_threadWorker->deleteLater();
}

感谢您的评论,此解决方案有效

int main(int argc, char *argv[])
{
    MyApplication app(argc, argv);
    return myApp.exec();
}

MyApplication::MyApplication( int& argc, char** argv ) : 
QApplication( argc, argv )
{
    m_window= new MyWidget();
    m_worker= new MyWorker();
    m_threadWorker = new QThread;
    m_worker->moveToThread(m_threadWorker);

    connect(this, SIGNAL(aboutToQuit()),m_worker,SLOT(quit()),Qt::QueuedConnection);

    connect(m_worker, SIGNAL(finished()), m_threadWorker, SLOT(quit()),Qt::DirectConnection);
    connect(m_threadWorker, SIGNAL(finished()), m_worker, SLOT(deleteLater()));

    m_threadWorker->start();
    m_window->show();
}

MyApplication::~MyApplication()
{
    m_threadWorker->wait();
    m_threadWorker->deleteLater();
    m_window->deleteLater();
    qDebug()<<"MyApplication::~MyApplication()";
}

MyWorker::quit()
{
    //longer ending operations freeing resources
    emit finished();
    qDebug() << "MyWorker::quit() emit finished()";
}

MyWorker::~MyWorker()
{
   qDebug() << "MyWorker::~MyWorker()";
}
intmain(intargc,char*argv[])
{
MyApplication应用程序(argc、argv);
返回myApp.exec();
}
MyApplication::MyApplication(int&argc,char**argv):
QApplication(argc、argv)
{
m_window=new MyWidget();
m_worker=新的MyWorker();
m_threadWorker=新的QThread;
m_-worker->moveToThread(m_-threadWorker);
连接(此,信号(aboutToQuit()),m_工作线程,插槽(quit()),Qt::QueuedConnection);
连接(m_-worker,SIGNAL(finished()),m_-threadWorker,SLOT(quit()),Qt::DirectConnection);
连接(m_threadWorker,信号(finished()),m_worker,插槽(deleteLater());
m_threadWorker->start();
m_窗口->显示();
}
MyApplication::~MyApplication()
{
m_threadWorker->wait();
m_threadWorker->deleteLater();
m_window->deleteLater();

qDebug()您应该等待线程退出。请参阅。文档中也有。谢谢,在第一个选项中,为什么会有m_threadWorker->deleteLater()2x?我的错,它是用来删除
连接中的
m_worker
-我通过编辑post解决了这个问题。这个解决方案不起作用,因为QApplication正在退出,而且worker析构函数没有一直被调用,但您帮助我解决了这个问题。这让我很惊讶。您能将您的解决方案作为一个应用程序发布吗回答?我很想知道你是如何解决这个问题的。