Qt: Multiple windows in a parent/child chain, parent does not close children?
I am trying to create multiple windows in a chain: window 1 is the parent of window 2, window 2 is the parent of window 3, etc. When I close one window, I would like all its children to close as well. Currently, if I close the top level window, all others close, as hoped, but closing, for example, window 2, only closes window 2, not window 3, etc. How should I be doing this? Thanks for your help!
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);
开发者_JAVA技巧QLabel* label = new QLabel("Window 2", this);
}
By default QApplication quits when the last primary window (window with no parent) is closed (see QApplication::lastWindowClosed signal), that is why closing your MainWindow closes everything.
Closing a widget doesn't delete it, unless the attribute Qt::WA_DeleteOnClose is set (see QWidget::close()). If you just want your windows to be closed, I think you have to reimplement closeEvent() to call close() on the children.
But if you want to delete them when closed, then set the attribute Qt::WA_DeleteOnClose. The children are automatically deleted when the parent is deleted.
You can overload closeEvent() in every widget that's supposed to have children. Then, either keep a list of your widgets to close in closeEvent(), or just call there deleteLater, which would delete both widget in question and its children.
Leiaz has already pointed out why the child-mainWindows' closeEvent(.) is not called. If you need to overload closeEvent(.) of the parent mainWindow to call closeEvent at each child because you do something in there (like storing window settings), you can insert this snippet:
auto childList = findChildren<QMainWindow*>();
for (auto child : childList)
{
child->close();
}
Note that the children's QMainWindow children will be called, as well, so there is no need to overload the child-mainWindows' closeEvent, too. In case that you want to only close QMainWindows that are direct children, use:
auto childList = findChildren<QMainWindow*>(QString(), Qt::FindDirectChildOnly);
for (auto child : childList)
{
child->close();
}
精彩评论