在模式对话框后面或关闭后打开对话框



我有一个应用程序,它有几个后台任务在非GUI线程中运行,有时可能需要一些用户交互,因此它们会向主线程发送信号,相应的插槽会创建一个对话框并向用户显示。同时,任务线程正在阻塞事件循环中等待。一旦用户回答对话框并关闭它,任务事件循环就会发出退出信号,任务就会继续。

然而,存在一个问题。在GUI线程中,我仍然可以使用不时显示一些模式对话框的应用程序。如果已经显示了一个模式对话框,然后后台任务请求打开另一个对话框,则此与任务相关的对话框将显示在模式对话框的前面。但这个新对话框不是模态对话框,模态对话框隐藏在它后面。因此,非模态对话框没有响应,应用程序感觉像被卡住了。

我的想法是始终在模态对话框后面显示新对话框,我相信QApplication::activeModalWidget()可以实现这一点。但我不知道该怎么做。如何在另一个对话框后面但仍在主窗口(两个对话框的父窗口(前面显示对话框?我试图在显示非模态对话框后调用QApplication::activeModalWidget()->activateWindow(),但他的操作会导致窗口闪烁,而且我仍然可以点击隐藏模态对话框的新非模态对话框。所以这不是一个完美的解决方案。

或者你看到其他解决方案了吗?

也许我可以实现一个对话框队列,一旦有任何模式对话框可见,那么新的后台任务相关对话框就不会显示,只会在模式对话框关闭后排队并显示。然而,这对我来说更脆弱的解决方案。

有什么想法吗?

更新:我重新定义了这个问题,添加了"或在它关闭后",因为这对我也有效。

我找到了一个似乎运行良好的解决方案,它只在关闭模态对话框后显示非模态对话框。

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);
}

这看起来既简单又稳健。

我想您正在寻找QWidget::raise((。在非模态对话框上调用dialog->show()之后,您应该能够使用QApplication::activeModalWidget()->raise()

如果你遇到的情况是,你有多个模态和非模态对话框,它们都以不同的顺序启动,这可能不足以解决问题。您可能会提出一个模态对话框,但其他对话框却落后于其他非模态对话框,从而再次陷入困境。您应该考虑保留对当前活动的模态对话框集合的引用,以便确保它们始终位于非模态对话框的顶部。

最新更新