Heavily based on posters Konstantin T.'s and Mike's ideas, I have developed two classes, MyWidget
and MyMainWindow
, which can use themselves and each other in their constructors to create child windows which will have their own task bar entries while still acting as children to their parent windows (i.e. getting automatically closed and destroyed upon termination of the parent window). MyWidget
replaces QWidget
and MyMainWindow
replaces QMainWindow
if such a behavior is desired.
my_widget.h:
#ifndef MY_WIDGET_H
#define MY_WIDGET_H
#include <QWidget>
#include <QMainWindow>
class MyMainWindow;
class MyWidget : public QWidget{
Q_OBJECT
public:
MyWidget(MyWidget* parent = 0){
if(parent){
connect(parent, SIGNAL(window_closed()),
this, SLOT(close()));
connect(parent, SIGNAL(destroyed(QObject*)),
this, SLOT(deleteLater()));
}
}
MyWidget(MyMainWindow* parent);
void closeEvent(QCloseEvent* event){
emit window_closed();
QWidget::closeEvent(event);
}
signals:
void window_closed();
};
class MyMainWindow : public QMainWindow{
Q_OBJECT
public:
MyMainWindow(MyMainWindow* parent = 0){
if(parent){
connect(parent, SIGNAL(window_closed()),
this, SLOT(close()));
connect(parent, SIGNAL(destroyed(QObject*)),
this, SLOT(deleteLater()));
}
}
MyMainWindow(MyWidget* parent){
connect(parent, SIGNAL(window_closed()),
this, SLOT(close()));
connect(parent, SIGNAL(destroyed(QObject*)),
this, SLOT(deleteLater()));
}
void closeEvent(QCloseEvent* event){
emit window_closed();
QMainWindow::closeEvent(event);
}
signals:
void window_closed();
};
#endif // MY_WIDGET_H
my_widget.cpp:
#include "my_widget.h"
MyWidget::MyWidget(MyMainWindow* parent){
connect(parent, SIGNAL(window_closed()),
this, SLOT(close()));
connect(parent, SIGNAL(destroyed(QObject*)),
this, SLOT(deleteLater()));
}
Example main.cpp:
#include <QApplication>
#include "my_widget.h"
int main(int argc, char* argv){
QApplication a(argc, argv);
MyWidget mw1{new MyWidget};
mw1.setWindowTitle("ctor: MyWidget(MyWidget*)");
mw1.show();
MyMainWindow mmw1{&mw1};
mmw1.setWindowTitle("ctor: MyMainWindow(MyWidget*)");
mmw1.show();
MyMainWindow mmw2{&mmw1};
mmw2.setWindowTitle("ctor: MyMainWindow(MyMainWindow*)");
mmw2.show();
MyWidget mw2{&mmw2};
mw2.setWindowTitle("ctor: MyWidget(MyMainWindow*)");
mw2.show();
return a.exec();
}
So the window chain is: mw1 -> mmw1 -> mmw2 -> mw2
where any window that is closed will also destroy all windows to its right and all windows in the chain will have their own task bar entries.
I'm sure there are more elegant ways of defining the constructors in my_widget.h
, but as a newbie this worked for me to obtain the exact behavior I needed. I'd appreciate to see better practices on my_widget.h
.