2010-12-16 17 views
15

Estoy intentando crear varias ventanas en una cadena: la ventana 1 es la ventana principal de la ventana 2, la ventana 2 es la ventana principal de la ventana 3, etc. Cuando cierro una ventana, me gustaría que todos sus elementos secundarios se cierren también. Actualmente, si cierro la ventana del nivel superior, todos los demás se cierran, como se esperaba, pero al cerrar, por ejemplo, la ventana 2, solo cierra la ventana 2, no la ventana 3, etc. ¿Cómo debería estar haciendo esto? ¡Gracias por tu ayuda!Qt: ¿Varias ventanas en una cadena padre/hijo, padre no cierra hijos?

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); 
} 

Respuesta

16

De forma predeterminada QApplication se cierra cuando se cierra la última ventana principal (ventana sin elemento principal) (ver QApplication::lastWindowClosed signal), por eso al cerrar su MainWindow se cierra todo.

Cerrar un widget no lo elimina, a menos que se haya establecido el atributo Qt :: WA_DeleteOnClose (consulte QWidget::close()). Si solo quiere que se cierren sus ventanas, creo que tiene que volver a implementar closeEvent() para llamar a close() en los elementos secundarios.

Pero si desea eliminarlos cuando se cierren, configure el atributo Qt :: WA_DeleteOnClose. Los niños se eliminan automáticamente cuando se elimina el padre.

+0

¡Eso fue lo que hizo! Agregar "w-> setAttribute (Qt :: WA_DeleteOnClose);" en mainwindow.cpp arriba trabajado. Me alegro de no tener que volver a implementar el evento close. ¡Gracias! – ishmael

+0

No sabía que el widget no se elimina al cerrar por defecto. Esto es útil. De alguna manera, establecer el atributo de la ventana en WA_DeleteOnClose para mi ventana PySide resolvió un problema de falla de segmentación. Ahora solo necesito descubrir por qué ... – lightalchemist

3

Puede sobrecargar closeEvent() en todos los widgets que se supone tener hijos. Luego, mantenga una lista de sus widgets para cerrar en closeEvent(), o simplemente llame allí deleteLater, que eliminaría tanto el widget en cuestión como sus hijos.

+0

recomendaría no hacer el seguimiento de los niños, ya que simplemente puede encontrar a los niños QMainWindow en CloseEvent. (por supuesto, esto solo es cierto a menos que haya niños a los que NO te gustaría cerrar ... por lo que esto tenga sentido) – IceFire

1

Leiaz ya ha señalado por qué no se llama al closeEvent (.) Principal de Windows hijo. (.) Si es necesario sobrecargar CloseEvent del mainWindow padre para llamar CloseEvent en cada niño, ya que hacer algo allí (como el almacenamiento de configuración de la ventana), se puede insertar este fragmento:

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

Tenga en cuenta que QMainWindow de los niños también se llamará a los niños, por lo que no es necesario sobrecargar el evento closePeter principal de Windows también. En caso de que desee sólo QMainWindows cercanos que son hijos directos, utiliza:

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