【问题标题】:Close all widgets in Qt except for some关闭 Qt 中的所有小部件,除了一些
【发布时间】:2014-07-24 12:17:09
【问题描述】:

我刚刚开始研究相当复杂的 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)并将信号重新发送到主事件循环?

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    所以我想出了一个先关闭模式对话框的解决方案:

    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 最终进入无限循环。

    【讨论】:

      【解决方案2】:

      使用这些函数来获取其他顶级小部件,包括模式对话框:

      QWidget * QApplication::activeModalWidget () [static]
      
      QWidget * QApplication::activePopupWidget () [static]
      

      你可以在这里阅读他们的信息http://qt-project.org/doc/qt-5/qapplication.html

      【讨论】:

      • 谢谢。我知道解决方案很好,只需要先关闭弹出窗口和模态框。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      相关资源
      最近更新 更多