关闭Qt中的所有小部件,除了一些

时间:2014-07-24 12:17:10

标签: c++ qt

我刚刚开始研究相当复杂的Qt应用程序。有一件事一直困扰着我。我们有一个"自动注销"功能在一段时间不活动后,大多数小部件都会关闭,并显示登录提示。它完成了这个插槽:

foreach(QWidget *w, qApp->topLevelWidgets()) {
   if ( w != loginDialog &&
        w != mainWindow &&
        !w->objectName().isEmpty() &&
        (w->isWindow() ) ) {
        w->close();
   }
}

基本上它会迭代除LoginDialog和MainWindow之外的所有小部件。这似乎工作正常,直到我们发现它没有正确处理模态对话框。特别是像QMessageBox::warning等对话框。现在的想法是先遍历模态小部件,然后再遍历普通小部件。您认为这是正确的方法吗?

UPD:对不起,但我不得不撤回对答案的接受。

我的问题似乎在这里描述https://blogs.kde.org/2009/03/26/how-crash-almost-every-qtkde-application-and-how-fix-it-0。它看起来像"关闭"请求在MessageBox的本地事件循环中处理。我应该重新解释一下我的问题:是否可以退出本地事件循环(即关闭MessageBox)并将信号重新发送到主事件循环?

2 个答案:

答案 0 :(得分:2)

所以我提出了一个解决方案,首先关闭模态对话框:

foreach(QWidget *w, qApp->topLevelWidgets()) {
   if ( w != loginDialog &&
    w != mainWindow &&
    w->isWindow() &&
    w->isModal() ) {
    w->close();
   }
}

这里重要的是不包含!w->objectName().isEmpty(),否则不会捕获匿名MessageBoxes。由于QWidget::close()在内部使用deleteLater(),因此在事件循环中以这种方式关闭小部件并正确处理删除似乎没问题。

我不能使用QApplication::activeModalWidget,因为我的loginDialog也是一个模态(但是隐藏),并且循环遍历activeModalWidget最终会进入无限循环。

答案 1 :(得分:1)

使用这些功能获取其他顶级小部件,包括模态对话框:

QWidget * QApplication::activeModalWidget () [static]

QWidget * QApplication::activePopupWidget () [static]

您可以在此处阅读http://qt-project.org/doc/qt-5/qapplication.html