我有一个应用程序,它有几个在非GUI线程中运行的后台任务,有时可能需要一些用户交互,所以它们向主线程发送信号,相应的插槽创建一个对话框,并将其显示给用户。同时,任务线程在阻塞事件循环中等待。一旦用户应答并关闭了对话框,任务事件循环就会被通知退出,并且任务会继续执行。
然而,有一个问题。在GUI线程中,我仍然可以使用应用程序,它会不时地显示一些模式对话框。如果已经显示了一个模式对话框,然后后台任务请求打开另一个对话框,则此与任务相关的对话框将显示在模式对话框的前面。但是这个新对话框不是模式对话框,模式对话框隐藏在它后面。因此,非模态的没有响应,应用程序感觉被卡住了。
我的想法是总是在模式对话框后面显示新的对话框,我相信我可以用QApplication::activeModalWidget()
得到这个对话框。但我不知道该怎么做。如何在主窗口(两个对话框的父窗口)之前显示另一个对话框?我试图在显示非模式对话框之后调用QApplication::activeModalWidget()->activateWindow()
,但他导致窗口闪烁,而且我仍然可以单击新的非模式对话框来隐藏模式对话框。所以这不是一个完美的解决方案。
或者,您是否看到了其他解决方案?
也许我可以实现一个对话框队列,一旦有任何模式对话框可见,那么新的与后台任务相关的对话框将不会显示,只有在模式对话框关闭后才会进入队列并显示。然而,这对我来说感觉更脆弱的解决方案。
有什么想法吗?
更新:我重新定义了这个问题,添加了“或在它关闭之后”,因为这对我也适用。
发布于 2020-04-30 04:23:52
我找到了一个似乎工作良好的解决方案,它只在模式对话框关闭后才显示非模式对话框。
QWidget *nonModalDialog = ... // creates the non-modal dialog
nonModalDialog->setAttribute(Qt::WA_DeleteOnClose);
QWidget *modalDialog = qApp->activeModalWidget();
if (modalDialog == nullptr)
{
// no modal dialog, we can show the non-modal one now
dialog->show();
}
else
{
// we must wait until the modal one is closed
QObject::connect(modalDialog, &QWidget::destroyed, nonModalDialog, &QWidget::show);
}
这看起来既简单又健壮。
发布于 2020-04-30 04:32:04
我想你是在找QWidget::raise()。在非模态对话框上调用dialog->show()
之后,您应该能够使用QApplication::activeModalWidget()->raise()
。
如果您遇到的情况是,您有多个模式和非模式对话框,都以不同的顺序启动,这可能不足以解决问题。您可能会引发一个模式对话框,结果却让其他模式对话框落后于其他非模式对话框,并最终再次被卡住。您应该考虑保留对当前活动的模式对话框集合的引用,以便可以确保它们始终位于非模式对话框的顶部。
https://stackoverflow.com/questions/61510381
复制相似问题