【问题标题】:Qt: Multiple windows in a parent/child chain, parent does not close children?Qt:父/子链中有多个窗口,父不关闭子?
【发布时间】:2011-05-26 06:28:13
【问题描述】:

我正在尝试在一个链中创建多个窗口:窗口 1 是窗口 2 的父窗口,窗口 2 是窗口 3 的父窗口,等等。当我关闭一个窗口时,我希望它的所有子窗口也关闭.目前,如果我关闭顶层窗口,所有其他窗口都会按希望关闭,但是关闭,例如窗口 2,只关闭窗口 2,而不关闭窗口 3,等等。我应该怎么做?感谢您的帮助!

main_window.cpp

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    QPushButton* button = new QPushButton("Open 1", this);
    connect(button, SIGNAL(clicked()), this, SLOT(on_button_clicked()));
}

void MainWindow::on_button_clicked() {
    window1 *w = new window1(this);
    w->show();
}

window1.cpp

window1::window1(QWidget *parent) : QWidget(parent)
{
    this->setWindowFlags(Qt::Window); // in order to have a free-standing window

    QPushButton* button = new QPushButton("Open 2", this);
    connect(button, SIGNAL(clicked()), this, SLOT(on_button_clicked()));
}

void window1::on_button_clicked() {
    window2 *w = new window2(this);
    w->show();
}

window2.cpp

window2::window2(QWidget *parent) : QWidget(parent)
{
    this->setWindowFlags(Qt::Window);

    QLabel* label = new QLabel("Window 2", this);
}

【问题讨论】:

    标签: windows qt parent


    【解决方案1】:

    您可以在每个应该有孩子的小部件中重载closeEvent()。然后,要么在closeEvent() 中保留要关闭的小部件列表,要么直接调用 deleteLater,这将删除相关小部件及其子小部件。

    【讨论】:

    • 我建议不要跟踪孩子,因为您可以简单地在 closeEvent 中找到 QMainWindow 孩子。 (当然,除非有你不想关闭的孩子,否则这才是正确的......为什么这可能是有道理的)
    【解决方案2】:

    默认情况下,QApplication 在最后一个主窗口(没有父窗口)关闭时退出(参见QApplication::lastWindowClosed signal), 这就是关闭 MainWindow 会关闭所有内容的原因。

    关闭小部件不会删除它,除非设置了属性 Qt::WA_DeleteOnClose(参见QWidget::close())。如果你只是想让你的窗口关闭,我认为你必须重新实现 closeEvent() 来调用孩子的 close() 。

    但是如果你想在关闭时删除它们,那么设置属性Qt::WA_DeleteOnClose。删除父级时,子级会自动删除。

    【讨论】:

    • 成功了!添加“w->setAttribute(Qt::WA_DeleteOnClose);”在上面的 mainwindow.cpp 中工作。很高兴我不必重新实现 closeEvent。谢谢!
    • 我不知道小部件在默认情况下不会在关闭时被删除。这很有帮助。不知何故,将我的 PySide 窗口的窗口属性设置为 WA_DeleteOnClose 解决了分段错误问题。现在我只需要弄清楚为什么......
    【解决方案3】:

    Leiaz 已经指出了为什么不调用 child-mainWindows 的 closeEvent(.)。如果您需要重载父 mainWindow 的 closeEvent(.) 以在每个子窗口中调用 closeEvent,因为您在其中执行了一些操作(例如存储窗口设置),您可以插入这个 sn-p:

    auto childList = findChildren<QMainWindow*>();
    for (auto child : childList)
    {
        child->close();
    }
    

    请注意,孩子的 QMainWindow 孩子也会被调用,因此也无需重载 child-mainWindows 的 closeEvent。如果您只想关闭直接子级的 QMainWindows,请使用:

    auto childList = findChildren<QMainWindow*>(QString(), Qt::FindDirectChildOnly);
    for (auto child : childList)
    {
        child->close();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      • 2017-02-08
      • 2013-02-14
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 2023-03-07
      相关资源
      最近更新 更多