aboutToQuit 期间的 Qt 异步操作

Posted

技术标签:

【中文标题】aboutToQuit 期间的 Qt 异步操作【英文标题】:Qt Asynchronous Action During aboutToQuit 【发布时间】:2010-02-26 19:33:06 【问题描述】:

当我的 Qt 应用程序正在关闭时,我需要执行一些异步清理活动。

我目前的方法是捕获 aboutToQuit 信号。我启动我的异步行为,然后应用程序关闭。有什么方法可以阻止 Qt 在我的异步行为完成之前关闭?

这可以通过捕获主窗口的 closeEvent 并在事件上调用 ignore() 来在 Windows 上工作。但在 Mac 上,当用户退出时,我的 ignore() 不被接受,并且应用程序在我的异步活动完成之前关闭。

谢谢。

【问题讨论】:

【参考方案1】:

如果您必须等待代码完成,为什么还要异步启动您的清理代码?

如果您没有将插槽作为 QueuedConnection 连接到 aboutToQuit,它应该会阻塞,直到您的清理代码完成。

但如果你真的想异步启动它,你必须手动同步它:

QSemaphore wait4CleanupDone;

class MyQuitHandler  ... public slots: void handleQuit(); ...  myQuitHandler;
void MyQuitHandler::handleQuit()  ... ; wait4CleanupDone.release(); 

int main(int argc, char** argv) 
  QApplication app(argc, argv);
  QObject::connect(&app, SIGNAL(aboutToQuit()), &myQuitHandler, SLOT(handleQuit()));
  ...
  int result = app.exec();
  wait4CleanupDone.acquire();
  return result;

但请注意,您的异步代码在某些情况下可能会被忽略:

“我们建议您将清理代码连接到 aboutToQuit() 信号,而不是将其放在应用程序的 main() 函数中。这是因为,在某些平台上,QApplication::exec() 调用可能不会返回. 例如,在Windows平台上,当用户注销时,Qt关闭所有顶层窗口后系统终止进程,因此无法保证应用程序有时间退出其事件循环并执行代码main() 函数的结尾,在 QApplication::exec() 调用之后。"

发件人:http://doc.trolltech.com/4.6/qapplication.html#exec

【讨论】:

基本上,我需要发出网络请求,但不想在等待响应进入时阻止 Qt(但也不希望 Qt 在我得到响应之前退出) .我们已经完全以另一种方式解决了这个问题,但我会标记你的答案,因为这将是解决问题的一种方法......【参考方案2】:

当我尝试这个时,很遗憾地崩溃了。

问题是连接调用,它已经使 main 的第 3 行崩溃。

int main(int argc, char *argv[]) 
    QApplication app(argc, argv);
    QObject::connect((QObject *)&app, SIGNAL(aboutToQuit()), (QObject *)&myQuitHandler, 
    SLOT(QuitApp()), Qt::QueuedConnection );

    QGraphicsScene scene(QRectf(0, 0, 640, 480));
    ..

在我开始使用 qgraphicsscene 后,不再有单个信号工作,因为我没有以任何信号工作的方式连接它。

到目前为止可以解决所有问题,如何在没有“连接”的情况下解决这个问题?

我马上就崩溃了:

传递给 C 运行时函数的参数无效。 退出代码 -1073741819

【讨论】:

以上是关于aboutToQuit 期间的 Qt 异步操作的主要内容,如果未能解决你的问题,请参考以下文章

是否可以指示浏览器在异步 DOM 操作期间不要渲染/重排/更新视口?

QT 异步函数和同步函数交换问题

无法连接来自 QApplication 的 aboutToQuit 信号

当 QNetworkAccessManager 完成时,Qt 检索在请求期间创建的附加数据

普通B/S架构模式同步请求与AJAX异步请求区别(个人理解)

Qt invokeMethod 异步调用