21

I'm working on a project in C++ and QT, and I want to open a new QWidget window, have the user interact with it, etc, then have execution return to the method that opened the window. Example (MyClass inherits QWidiget):

void doStuff(){

     MyClass newWindow = new Myclass();
     /* 
        I don't want the code down here to 
        execute until newWindow has been closed
      */
}

I feel like there is most likely a really easy way to do this, but for some reason I can't figure it out. How can I do this?

Jarek
  • 1,320
  • 3
  • 11
  • 19

3 Answers3

31

Have MyClass inherit QDialog. Then open it as a modal dialog with exec().

void MainWindow::createMyDialog()
{
  MyClass dialog(this);
  dialog.exec();
}

Check out http://qt-project.org/doc/qt-4.8/qdialog.html

mavroprovato
  • 8,023
  • 5
  • 37
  • 52
Mark Beckwith
  • 1,942
  • 1
  • 18
  • 22
  • Using a QDialog has side effects - it's rendered differently by default, and the Escape key closes it. I believe @56ka's answer avoid this. – Jonathan Sep 10 '15 at 21:31
  • 2
    In case anyone else is tempted to use `setModal()` and `show()`, here's what http://doc.qt.io/qt-5/qdialog.html#modal-dialogs says: *"The most common way to display a modal dialog is to call its exec() function. (...) An alternative is to call setModal(true) or setWindowModality(), then show(). Unlike exec(), show() returns control to the caller immediately."* – waldyrious Dec 14 '16 at 19:30
  • 1
    Qt5 docs say `QDialog::exec()` is to be avoided. So this answer is no longer best practice (if it ever was). – Joachim W Mar 08 '19 at 17:21
15

An other way is to use a loop which waits on the closing event :

#include <QEventLoop>

void doStuff()
{
    // Creating an instance of myClass
    MyClass myInstance;
    // (optional) myInstance.setAttribute(Qt::WA_DeleteOnClose);  
    myInstance.show();

    // This loop will wait for the window is destroyed
    QEventLoop loop;
    connect(this, SIGNAL(destroyed()), & loop, SLOT(quit()));
    loop.exec();
}
HaskellElephant
  • 9,819
  • 4
  • 38
  • 67
56ka
  • 1,463
  • 1
  • 21
  • 37
  • You'll need to connect(&myInstance, SIGNAL(destroyed()), & loop, SLOT(quit())); instead of connect(this, ...) - otherwise you're waiting for your current dialog to be destroyed instead of the myInstance Dialog. – Sumyrda - remember Monica Jun 08 '22 at 08:52
0

Why not put the code you don't want to be executed till the window has closed in a separate function and connect this as a SLOT for the window's close SIGNAL?

dirkgently
  • 108,024
  • 16
  • 131
  • 187
  • Thanks, that sounds like a good idea. How would I do this? I've never hard-coded signals/slots, only used them through QTDesigner. – Jarek May 02 '09 at 19:39