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

时间:2020-04-29 19:45:06

标签: c++ qt

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

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

我的想法是始终在模式对话框的后面显示新对话框,我相信我可以使用QApplication::activeModalWidget()获得该对话框。但是我不知道该怎么做。如何在另一个对话框之后但仍在主窗口(这是两个对话框的父窗口)的前面显示一个对话框?在显示非模态对话框后,我尝试调用QApplication::activeModalWidget()->activateWindow(),但其原因导致窗口闪烁,此外,我仍然可以单击进入新的非模态对话框,以隐藏模态对话框。因此,这不是一个完美的解决方案。

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

也许我可以实现一系列对话框,并且一旦可见任何模式对话框,那么新的后台任务相关对话框将不会显示,只有在模式对话框关闭后才排队并显示。但是,这对我来说感觉更脆弱。

有什么想法吗?

更新:我通过添加“或关闭后”来重新定义问题,因为这对我也适用。

2 个答案:

答案 0 :(得分:0)

我找到了一个似乎运行良好的解决方案,并且仅在关闭模式对话框后才显示非模式对话框。

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

这似乎简单而健壮。

答案 1 :(得分:0)

我认为您正在寻找QWidget::raise()。在非模式对话框中调用QApplication::activeModalWidget()->raise()之后,您应该可以使用dialog->show()

如果您遇到有多个模式对话框和非模式对话框(以不同顺序启动)的情况,那么这可能不足以解决问题。您可能只引发一个模态对话框,而将其他模态对话框置于其他非模态对话框的后面,并最终再次卡住。您应该考虑保留对当前处于活动状态的模态对话框的集合的引用,以确保它们始终位于非模态对话框的顶部。