I made a non-modal dialog (see the code below). How can I close all dialogs by clicking a button?
mainwindow.h
private:
Ui::MainWindow *ui;
Dialog *dialog;
};
mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{
dialog = new Dialog(this);
dialog->show();
}
void MainWindow::on_closeButton_Clicked()
{
//here I want to close all opened dialogs.
}
Title and question text are a bit incongruently. Where title asks
I want to close all dialogs by clicking a button
the question text exposes a sample code for one dialog only where pointer to dialog is available as member.
This answer refers to the title itself:
One option to close all opened dialogs would be just to remember their pointers in a std::vector<QDialog*>
and call hide()
for them e.g. in MainWindow::on_closeButton_Clicked()
.
However, the book-keeping of dialogs in an extra vector would make me uncomfortable. Actually, there is already such storage as the dialog constructors are called with the MainWindow
pointer as parent (which is surely derived from QMainWindow
or QWidget
).
Every QObject
stores a child list of objects which are constructed with the former as parent. (This is the Qt way to simplify memory management.) This is what can be used here → all created dialogs should occur in this list.
I made a small sample testQCloseAllDlgs.cc
to test/illustrate this:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QMainWindow qWin;
qWin.setWindowTitle("Close Dialogs Test");
for (int i = 0; i < 3; ++i) {
QDialog *pQDlg = new QDialog(&qWin);
pQDlg->setWindowTitle(QString("Dialog %1").arg(i + 1));
//pQDlg->show();
}
QPushButton qBtnCloseDlgs("Close All Dialogs");
qWin.setCentralWidget(&qBtnCloseDlgs);
qWin.show();
for (QObject *pQChild : qWin.children()) {
if (QDialog *pQDlg = dynamic_cast<QDialog*>(pQChild)) {
pQDlg->show();
}
}
// install signal handlers
QObject::connect(&qBtnCloseDlgs, &QPushButton::clicked,
[&qWin](bool){
for (QObject *pQChild : qWin.children()) {
if (QDialog *pQDlg = dynamic_cast<QDialog*>(pQChild)) {
pQDlg->hide();
}
}
});
// run time loop
return app.exec();
}
and a resp. project file testQCloseAllDlgs.pro
:
SOURCES = testQCloseAllDlgs.cc
QT += widgets
Compiled and tested in cygwin64:
$ qmake-qt5 testQCloseAllDlgs.pro
$ make && ./testQCloseAllDlgs
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQCloseAllDlgs.o testQCloseAllDlgs.cc
g++ -o testQCloseAllDlgs.exe testQCloseAllDlgs.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
Qt Version: 5.9.4
When the Close All Dialogs button is clicked (the only widget of main window) all 3 dialogs vanish.
Please, note that hide()
doesn't delete the dialogs – the become invisible only.
This is what I prefer personally → to recycle dialogs.
show()
method might be called again.Alternatetively, dialogs might be deleted. (They will be excluded from the children list of parent automatically.) This is another point where it will pay off to use the already existing QObject::children()
member instead of an own book-keeping because the latter might be not quite easy to implement correctly.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments