Important: Please read the Qt Code of Conduct -

Problems with SIGNAL(accept()) and SIGNAL(reject()) and QMessageBox

  • Hello,

    I want to use QMessageBox asynchronously, but it looks as if there are some really strange things going on:

    When using the StandardButtons (e.g. OK and Cancel) the SIGNAL accept() and SIGNAL reject() are not emitted at all.

    When using addButton(QString,ButtonRole), the signals are emitted but exactly in wrong way. Clicking on the AcceptRole emits SIGNAL reject() and vice versa.

    I've created some demo:

    It gives the following output:

    @Finished 0
    Button clicked "Accept"@


    @Finished 1
    Button clicked "Reject"@

    Does anyone know what's wrong with my code?

    Best Regards,


  • Hi.
    I confirmed this problem and googled the reason why these strange things happen.

    I wonder the problem(2) may be bug of Qt.

    The solution is just swap line 23 and line 24 in your code.
    (I'm confused and I would like to know better solution.)


  • Thx, you are right... but this is a very bad behavior... I guess this should be fixed.

  • I ve checked the library source (qt 4.7.3) and found the following:
    @#src/gui/dialogs/qdialog.cpp line 586
    void QDialog::done(int r)
    if (r == Accepted)
    emit accepted();
    else if (r == Rejected)
    emit rejected();

    @#src/gui/dialogs/qmessagebox.cpp line 463
    void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
    q->done(execReturnCode(button)); // does not trigger closeEvent

    @#src/gui/dialogs/qmessagebox.cpp line 452
    int QMessageBoxPrivate::execReturnCode(QAbstractButton *button)
    int ret = buttonBox->standardButton(button);
    if (ret == QMessageBox::NoButton) {
    ret = customButtonList.indexOf(button); // if button == 0, correctly sets ret = -1
    } else if (compatMode) {
    ret = oldButton(ret);
    return ret;

    This means:

    • When using StandardButtons the return value is never QDialog::Accepted==0 or QDialog::Rejected==0. Thus we never receive the SIGNALS accepted() or rejected().
    • When using 'customButtons' (e.g. with addButton()) the position in the list does decide, which signal is emitted: The first inserted button will trigger the SIGNAL rejected() while the second button triggers the SIGNAL accepted(), independent of their ButtonRole!

    Imho this is a dubious implementation :s


    PS: Since SIGNAL done(int) uses the same return code, only the pointer-value of buttonClicked() gives us a valid statement about user's choice. But preserving these buttons is against my intention of a asynchronous QMessageBox handling.

  • I agree, this is VERY dubious implementation AND documentation.

    The documentation should mention that accepted() and rejected() signals of QMessageBox are never emitted when using StandardButtons. As well as the other problem documented above.

    A casual reading of:

    bq. QMessageBox::AcceptRole 0 Clicking the button causes the dialog to be accepted (e.g. OK).

    would lead one to believe that an accepted() signal would be emitted. It should say something like "Clicking the button causes the dialog to be closed, the finished() signal to be emitted, the result of the dialog (whether from an exec() call or the finished() signal) to be the StandardButton enum value of the button that was clicked, and an accepted or rejected signal to be emitted if custom buttons are used (where the order of the custom buttons determines which of accepted or rejected signals are emitted.) Phew, its difficult to concisely say what the behaviour is, and what I said may not be correct.

    Is the solution to connect to finished(), and make the slot dispatch the result?

  • now I refreshed my memory why I did my own message box :)

    besides, also the style sheet does not work as expected for QMessageBox

Log in to reply