Qt: Несколько окон в родительской/дочерней цепочке, родитель не закрывает детей?

Я пытаюсь создать несколько цепочек в цепочке: окно 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);
}

Ответы

Ответ 1

По умолчанию QApplication завершает работу, когда последнее первичное окно (окно без родителя) закрыто (см. QApplication:: lastWindowClosed signal), поэтому закрытие MainWindow закрывает все.

Закрытие виджета не удаляет его, если не установлен атрибут Qt:: WA_DeleteOnClose (см. QWidget:: close()). Если вы просто хотите, чтобы ваши окна были закрыты, я думаю, вам нужно переопределить closeEvent(), чтобы вызвать close() для детей.

Но если вы хотите удалить их при закрытии, установите атрибут Qt:: WA_DeleteOnClose. Дети автоматически удаляются при удалении родителя.

Ответ 2

Вы можете перегрузить closeEvent() в каждом виджете, который должен иметь детей. Затем либо сохраните список ваших виджетов, чтобы закрыть его в closeEvent(), либо просто вызовите deleteLater, который удалит оба виджета, о которых идет речь, и его детей.

Ответ 3

Лейаз уже указал, почему не закрывается дочерний mainWindows 'closeEvent (.). Если вам нужно перегрузить closeEvent (.) Родительского mainWindow, чтобы вызвать closeEvent у каждого дочернего элемента, потому что вы что-то там делаете (например, сохранение настроек окна), вы можете вставить этот фрагмент:

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

Обратите внимание, что дети детей QMainWindow также будут вызваны, поэтому нет необходимости также перегружать дочерний элемент mainWindows. Если вы хотите закрыть только QMainWindows, которые являются прямыми дочерними, используйте:

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