2010-12-16 5 views
15

Próbuję utworzyć wiele okien w łańcuchu: okno 1 jest rodzicem okna 2, okno 2 jest rodzicem okna 3 itd. Kiedy zamykam jedno okno, chciałbym, aby wszystkie jego dzieci również się zamknęły. Obecnie, gdy zamykam okno najwyższego poziomu, wszystkie inne zamykają się, tak jak się spodziewano, ale zamykając, na przykład, okno 2, zamyka tylko okno 2, nie okno 3 itp. Jak powinienem to robić? Dzięki za pomoc!Qt: Wiele okien w łańcuchu nadrzędnym/podrzędnym, rodzic nie zamyka dzieci?

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

Odpowiedz

16

Domyślnie QApplication kończy się, gdy ostatnie okno główne (okno bez rodzica) jest zamknięte (patrz QApplication::lastWindowClosed signal), , dlatego zamknięcie MainWindow zamyka wszystko.

Zamknięcie widgetu nie powoduje usunięcia go, chyba że ustawiono atrybut Qt :: WA_DeleteOnClose (patrz QWidget::close()). Jeśli chcesz tylko zamknąć okna, myślę, że musisz ponownie zaimplementować closeEvent(), aby wywołać close() na elementach potomnych.

Ale jeśli chcesz je usunąć po zamknięciu, ustaw atrybut Qt :: WA_DeleteOnClose. Dzieci są automatycznie usuwane po usunięciu rodzica.

+0

To wystarczy! Dodanie "w-> setAttribute (Qt :: WA_DeleteOnClose);" w mainwindow.cpp powyżej pracował. Cieszę się, że nie musiałem ponownie wdrażać closeEvent. Dzięki! – ishmael

+0

Nie wiedziałem, że widget nie jest domyślnie usuwany przy zamknięciu. Jest to pomocne. W jakiś sposób ustawienie atrybutu okna na WA_DeleteOnClose dla mojego okna PySide rozwiązało problem z uszkodzeniem segmentacji. Teraz po prostu muszę dowiedzieć się, dlaczego ... – lightalchemist

3

Można przeciążać closeEvent() w każdym widget, który powinien mieć dzieci. Następnie albo pozostaw listę widżetów do zamknięcia w closeEvent(), albo po prostu wywołaj tam deleteLater, który usunie oba widgety i ich dzieci.

+0

Polecam nie śledzenie dzieci, bo można po prostu znaleźć dzieci QMainWindow w closeEvent. (Oczywiście, to prawda, chyba że są dzieci, których nie chciałbyś zamknąć ... dlaczego to ma sens) – IceFire

1

Leiaz już wskazał, dlaczego nie jest wywoływana funkcja closeEvent (.) Child-mainWindows.(). Jeżeli trzeba przeładowywać closeEvent z MainWindow macierzystego zadzwonić closeEvent u każdego dziecka, ponieważ można zrobić coś tam (jak zapisywania ustawień okna), można wstawić ten fragment:

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

Zauważ, że QMainWindow dziecięcy dzieci będą również nazywane, więc nie ma również potrzeby przeciążania akcji childEventWindows. W przypadku, gdy chcesz tylko bliskie QMainWindows które są bezpośrednimi dzieci, należy:

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