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

12,637

Solution 1

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.

Solution 2

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.

Share:
12,637
Rich
Author by

Rich

Software developer at yWorks GmbH. Usually I'll answer questions here about Java, C#, PowerShell, batch files, random numbers, regular expressions and Unicode. At work I primarily deal with C#, Java and JavaScript. My interests are mostly HCI, Interaction Design and UX. Recently I18n joined that list as well. That does not mean I have profound knowledge in either of those fields, just that I am interested in them. Note: People contacting me outside SO/SE is fine, but for discussing their own questions or answers SO already provides a mechanism, namely edits and comments. So please use those things first. I do hang around on Freenode as Hypftier, though.

Updated on October 21, 2022

Comments

  • Rich
    Rich over 1 year

    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?

  • Rich
    Rich about 11 years
    Note: This works in the case where no dialog result is needed. If you still need the argument from finished() then I don't know what happens. But for my problem here that was enough.
  • Rich
    Rich about 11 years
    I couldn't find that advice for exec again anywhere in the docs, could be that it just was on some random blog of dubious value. And thanks for the attribute. I've searched for at least an hour (+build time for the experiments) until I stumbled on the idea to just connect the finished signal (which wasn't optimal but sufficient for my purpose).
  • Chris
    Chris about 11 years
    It's actually documented quite clearly in this .cpp file qt.gitorious.org/qt/qt/blobs/4.8/src/gui/dialogs/… ;)
  • Rich
    Rich about 11 years
    I was referring to what I wrote in the question regarding processEvents. That exec stops the parent event loop is fairly obvious, because it's blocking; also that it has to create a new one for the dialog.