Featured image of post Qt QDialog Source Code Analysis - Differences Between open(), exec(), and show() Methods

Qt QDialog Source Code Analysis - Differences Between open(), exec(), and show() Methods

QDialog is used to create dialog windows. It provides three main display methods `open()`, `exec()`, and `show()`. This article will analyze the QDialog source code to deeply understand the differences between these methods and their appropriate use cases.

Introduction

In the Qt framework, QDialog is used to create dialog windows. It provides three main display methods: open(), exec(), and show(). While all these methods can display dialogs, they differ significantly in behavior and usage scenarios. This article will analyze the QDialog source code to understand these differences in depth.

Brief Overview of QDialog Display Methods

First, let’s briefly understand these three methods:

  • show(): Non-modal dialog display
  • open(): Window-modal dialog display, returns immediately
  • exec(): Modal dialog display, blocks until user closes

Analysis of show() Method

show() is a QWidget method inherited by QDialog:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
void QWidget::show()
{
    Qt::WindowState defaultState = QGuiApplicationPrivate::platformIntegration()->defaultWindowState(data->window_flags);
    if (defaultState == Qt::WindowFullScreen)
        showFullScreen();
    else if (defaultState == Qt::WindowMaximized)
        showMaximized();
    else
        setVisible(true); // Don't call showNormal() as not to clobber Qt::Window(Max/Min)imized
}

void QWidget::setVisible(bool visible)
{
    if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) == !visible)
        return;

    // Remember that setVisible was called explicitly
    setAttribute(Qt::WA_WState_ExplicitShowHide);

    Q_D(QWidget);
    d->setVisible(visible);
}

Characteristics:

  • Non-modal display (by default)
  • Returns immediately without blocking the calling thread
  • Allows interaction with other application windows
  • Doesn’t automatically create an event loop

Example usage:

1
2
3
QDialog *dialog = new QDialog(this);
// Setup dialog content...
dialog->show();

Analysis of open() Method

open() was introduced in Qt 4.5 for window-modal dialogs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
void QDialog::open()
{
    Q_D(QDialog);

    // Get current window modality
    Qt::WindowModality modality = windowModality();
    if (modality != Qt::WindowModal) {
        d->resetModalityTo = modality;
        d->wasModalitySet = testAttribute(Qt::WA_SetWindowModality);
        setWindowModality(Qt::WindowModal);
        setAttribute(Qt::WA_SetWindowModality, false);
#ifdef Q_OS_MAC
        // Set as sheet on macOS
        setParent(parentWidget(), Qt::Sheet);
#endif
    }

    setResult(0);
    show();
}

Characteristics:

  • Window-modal display (blocks parent window interaction)
  • Returns immediately
  • Saves original modality state before setting window modality
  • Asynchronous operation, suitable for signal-slot event handling

Example usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
QDialog *dialog = new QDialog(this);
// Setup dialog content...
connect(dialog, &QDialog::finished, this, &MyWidget::handleDialogResult);
dialog->open();

// Handle result in slot
MyWidget::handleDialogResult(int result)
{
    if (result == QDialog::Accepted)
        // Handle acceptance
    else if (result == QDialog::Rejected)
        // Handle rejection
}

Analysis of exec() Method

exec() is the traditional method for modal dialogs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int QDialog::exec()
{
    Q_D(QDialog);

    if (Q_UNLIKELY(d->eventLoop)) {
        qWarning("QDialog::exec: Recursive call detected");
        return -1;
    }

    bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_DeleteOnClose, false);

    d->resetModalitySetByOpen();

    bool wasShowModal = testAttribute(Qt::WA_ShowModal);
    setAttribute(Qt::WA_ShowModal, true);
    setResult(0);

    show();

    QPointer<QDialog> guard = this;
    if (d->nativeDialogInUse) {
        d->platformHelper()->exec();
    } else {
        QEventLoop eventLoop;
        d->eventLoop = &eventLoop;
        (void) eventLoop.exec(QEventLoop::DialogExec);
    }
    if (guard.isNull())
        return QDialog::Rejected;
    d->eventLoop = nullptr;

    setAttribute(Qt::WA_ShowModal, wasShowModal);

    int res = result();
    if (d->nativeDialogInUse)
        d->helperDone(static_cast<QDialog::DialogCode>(res), d->platformHelper());
    if (deleteOnClose)
        delete this;
    return res;
}

Characteristics:

  • Modal display (application-modal by default)
  • Blocks calling thread until dialog closes
  • Creates and executes local event loop
  • Returns dialog result code (QDialog::Accepted/Rejected)
  • Contains recursive call detection
  • Prevents dialog deletion during display

Example usage:

1
2
3
4
5
6
7
QDialog dialog(this);
// Setup dialog content...
if (dialog.exec() == QDialog::Accepted) {
    // Handle acceptance
} else {
    // Handle rejection
}

Best Practice Recommendations

The Qt documentation explicitly recommends using open() over exec():

Note: Avoid using exec(); instead, use open(). Unlike exec(), open() is asynchronous and doesn’t spin an additional event loop. This prevents potential bugs (e.g., deleting the dialog’s parent while open via exec()). When using open(), connect to the finished() signal to handle dialog closure.

However, note that on macOS this enables sheet styling with system-default masking. If your project implements custom masking, this might cause visual conflicts.

Also be aware that exec() has limitations when creating nested dialogs - you can’t hide DialogA to show DialogB and then restore DialogA after DialogB closes.

Conclusion

Through analyzing QDialog’s source code, we gain deep understanding of how open(), exec(), and show() work differently. This knowledge helps make informed decisions when implementing dialogs in Qt applications.