Крупной на основе плакатов идеи Майка Константин Т. х и, я разработал два класса, MyWidget
и MyMainWindow
, которые могут использовать себя и друг друга в своих конструкторах создавать дочерние окна, которые будут иметь свои собственные записи на панели задач в то время как все еще действуя как дети в их родительские окна (т.е. автоматически закрываются и уничтожаются по окончании родительского окна). MyWidget
заменяет QWidget
и MyMainWindow
заменяет QMainWindow
, если такое поведение необходимо.
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()));
}
Пример главной.каст:
#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();
}
Так окно цепи: mw1 -> mmw1 -> mmw2 -> mw2
где любое окно, которое закрывается также уничтожить все окна справа от нее и все окна в цепочке будут иметь свои собственные записи на панели задач.
Я уверен, что есть более элегантные способы определения конструкторов в my_widget.h
, но в качестве новичка это работало для меня, чтобы получить точное поведение, в котором я нуждался. Я был бы рад увидеть лучшие практики на my_widget.h
.
Почему вы подключаетесь к 'deleteLater()' slot, а не 'close()'? возможно, у вас должно быть имя вашего сигнала как 'closed()' вместо этого? – Mike
Я запустил его, но чтобы получить точное поведение, которое я хотел, мне пришлось взять совет @ Майка и сначала переименовать сигнал в нечто иное, чем 'close()' и подключить его к слоту 'close()'. Когда я так устроен, я могу наследовать новые окна из «PrimaryWindow», сохраняя поведение, которое я хочу. Механизм сигнала-слота, описанный здесь, намного более умен, чем тот, который у меня был в моих классах, и он делает то, что я хочу; однако я подожду некоторое время, прежде чем я приму этот ответ, потому что мне очень хотелось бы знать, можно ли это сделать с помощью флажков с окнами. Спасибо вам как – Deniz
@Deniz. Чтобы подражать владельцу 'QObject', вы можете подключить' destroy' от родителя к слоту 'deleteLater'. (что-то вроде 'connect (parent, SIGNAL (destroy()), это, SLOT (deleteLater());') в дополнение к подключению нашего 'closed()' сигнала к 'close()' slot. – Mike