Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show a window in Qt and deleting it as soon as it's closed?

Tags:

qt

qdialog

As a very simple example, I want to show a dialog in Qt when I press a button. The usual pattern for this (in the application I'm currently working on) seems to be as follows:

class MainWindow {
  ...
private slots:
  buttonClicked();
  ...
private:
  ChildWindow * childWindow;
}

MainWindow::MainWindow(QWidget * parent) : QWidget(parent) {
  ...
  childWindow = new ChildWindow(this);
  ...
}

MainWindow::buttonClicked() {
  childWindow.show();
}

Coming from .NET and Windows Forms (and because I don't need access to that object from elsewhere in the class) the following pattern is more familiar to me:

button1_Clicked(object sender, EventArgs e) {
  ChildWindow f = new ChildWindow();
  f.Show();
}

The local variable means I don't have yet another instance field and also that the window won't linger around in memory for much longer than necessary. A direct translation of that to C++ would be a bit ugly because no one would clear up afterwards. I tried the following things:

  1. shared_ptr. No luck, the window is deleted as soon as the method ends which means the new window appears for a split second and vanishes again. Not so good.

  2. exec() instead of show(). This would work for modal dialogs, but documentation seemed to imply that it also stops the event loop and that you should call QApplication::processEvents() regularly if it still needs to be updated. I understand little enough here but I guess it's not too nice either.

  3. deleteLater(). Sadly, just showing a window doesn't block deleteLater so it vanishes as soon as it appears.

Is there a nice option to just clean up after the window when I close it?

like image 637
Joey Avatar asked Apr 04 '13 14:04

Joey


2 Answers

childWindow->setAttribute( Qt::WA_DeleteOnClose );

Also note that calling exec() will block execution of the calling event loop, but will spawn its own event loop, so no calls to processEvents() should be necessary.

like image 184
Chris Avatar answered Nov 19 '22 12:11

Chris


You can connect the finished() signal of th dialog to its deleteLater slot:

ChildWindow * d = new ChildWindow(this);
connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater()));
d->show();

This way it will be deleted as soon as you close the dialog.

like image 24
Joey Avatar answered Nov 19 '22 13:11

Joey