退出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()";
}
问题在于,Worker析构函数通常不运行。我担心未正确终止工作进程会不时导致应用程序崩溃。我在该线程中使用摄像头,因此如果摄像头循环处于活动状态,则释放会花费更多时间,并且通常不会发出完成对象,因此永远不会调用析构函数。
答案 0 :(得分:2)
问题在于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();
}
但是,这将在等待工作人员完成时“冻结”您的应用程序。如果您想在等待时保持响应状态,请改用QEventLoop
中的本地MyApplication::stopWorker
并将其用作:
MyApplication::stopWorker() {
QEventLoop stopLoop;
connect(m_threadWorker, &QThread::finished,
&stopLoop, &QEventLoop::quit);
QMetaObject::invokeMethod(m_worker, "quit");
stopLoop.exec();
m_threadWorker->deleteLater();
}
答案 1 :(得分:1)
感谢您的评论,此解决方案有效
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()";
}