【问题标题】:Qt UI Closing orderQt UI 关闭顺序
【发布时间】:2014-01-20 22:05:05
【问题描述】:

我的项目中有一个 QMainWindow 作为 GUI 的中心,这个窗口可以打开一个新窗口。我希望当用户关闭主窗口时,主窗口打开的所有其他窗口也将关闭。

我试图在主窗口的析构函数中放置一个信号来调用另一个窗口close() 槽,但它不起作用。我只能通过在主窗口中创建一个closeEvent() 来完成这项工作,它将向另一个窗口关闭插槽发送信号。

所以我的问题是,Qt 如何处理所有这些?如果窗口存在,如果主窗口在其析构函数中触发它,为什么它们无法接收到信号?我将析构函数中的其他信号发送给其他线程,它们接收它们就好了。

【问题讨论】:

  • 为什么不让主窗口成为应用程序所有其他“逻辑子”窗口的父窗口?在这种情况下,关闭主窗口将关闭所有子窗口。
  • 我将主窗口的父窗口设为窗口的父窗口...它只是构造函数中的this 吗?
  • 我猜不是...我只是放置了一个this 并且窗口被渲染在主窗口空间内
  • 使用 move 成员函数将新窗口移动到您希望它显示的位置。还是您想说您没有第二个窗口?如果您使用 QWidget 派生类作为窗口(并有一个父窗口),您可以使用 setWindowFlags(Qt::Window); (查看文档以获取其他选项,而不是 Qt ::窗口)
  • 我只是在一些文档中发现了一个 QWidget 的子类...这是错的吗?

标签: c++ qt


【解决方案1】:

我会这样做:

void MyMainWindow::closeEvent(QCloseEvent *e)
{
    foreach (QWidget *widget, QApplication::topLevelWidgets()) {
        if (widget != this) { // avoid recursion.
            widget->close();
        }
    }
    e->accept();
}

一旦主窗口关闭,上面的代码就会搜索并关闭所有顶层窗口。

【讨论】:

  • 我想这太多了,因为将主窗口设置为其他窗口的父窗口就可以了
【解决方案2】:

您的错误非常简单:在关闭窗口的那一刻没有调用析构函数。您已经发现在closeEvent 中发出信号是一种解决方案,所以我不太明白问题出在哪里。

如果你坚持在析构函数中发出信号,你必须做两件事:

  1. 在堆上分配小部件。

  2. 在小部件上设置Qt::WA_DeleteOnClose 属性。

int main() {
  QScopedPointer<MyWidget> widget(new MyWidget);
  widget->setAttribute(Qt::WA_DeleteOnClose);
  ...
}

【讨论】:

  • 这不是问题,我只是想了解幕后发生了什么......我的意思是,为什么信号没有发送到窗口而是发送到其他线程。
  • 我想更多地了解 Qt 关闭 UI 的方式,事情的顺序,但为了结束这个答案,我决定将你的答案标记为答案,因为它涵盖了正在发生的事情。谢谢!
【解决方案3】:

有两种方法可以解决这个问题,这两种方法都对我有用:

方法一: 如果要在关闭时删除它们,则设置属性 Qt::WA_DeleteOnClose。删除父级时,子级会自动删除。

为您的 QMainWindow 实例调用 setAttribute(Qt::WA_DeleteOnClose) 方法 例如:我的 main.cpp

    #include "st.h"
    #include <QtGui/QApplication>

    int main(int argc, char *argv[])
    {
  QApplication a(argc, argv);
  St *w = new St();
  w->setAttribute(Qt::WA_DeleteOnClose);
  w->show();
  return a.exec();
    }

还将“this”指针传递给您正在创建的任何子窗口。 但是你已经在堆上而不是在堆栈上创建了 QMainWindow 实例,否则你的应用程序将会崩溃。

方法2:

为您的 QMainWindow 重载 closeEvent 方法,并在该关闭事件方法中调用 所有孩子的 deleteLater() 方法。

     void St::closeEvent(QCloseEvent *c)
     {
   m_b->deleteLater();//This is a pushbutton
   odlg->deleteLater();//This is child dialog
       //both are children of QMainWindow

     }

【讨论】:

  • @vahancho 是否会关闭所有顶级小部件,即使它不是主窗口的子窗口?
  • 是的,它应该关闭所有顶级小部件。附言您的评论出现在错误的帖子下:)
猜你喜欢
  • 1970-01-01
  • 2021-04-04
  • 2021-11-02
  • 2013-11-11
  • 2013-09-17
  • 2010-10-11
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多