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

Joey picture Joey · Apr 4, 2013 · Viewed 12.2k times · Source

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?

Answer

Chris picture Chris · Apr 4, 2013
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.