Important: Please read the Qt Code of Conduct -

QMessageBox.exec() blocks calling slot

  • I have a window with editable values in a table and “send” button.
    There are 2 signals and 2 related slots – one pair is for data changed and another pair is for button click:
    connect(send, SIGNAL(clicked()), this, SLOT(send_parameters()));
    connect(_table, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(item_changed(QTableWidgetItem*)));

    If I change data in a table cell and click send button without preliminary leaving the cell, my app calls item_changed() slot and after that it calls send_parameters() slot as expected.

    However, if in item_changed() a message box pops up, after message box closing send_parameters() is never called.

    Can someone explain?

    Thank you, Alex

    void MyDialog::item_changed(QTableWidgetItem* item)
       //works fine
    void MyDialog::item_changed(QTableWidgetItem* item)
       //blocks call to send_parameters
       QMessageBox msgBox;

    [Added code tags ~kshegunov]

  • Just a wild guess:

    • You press the send button.
    • Pressing the send button the cell looses focus and emits the itemChanged signal.
    • While handling the itemChanged a message box pops up.
    • You close the message box. The mouse is most likely not over the button anymore.

    My guess is that the button saw the mouse press event (which lead to the cell loosing focus) but then did not see the mouse release event and so did not see a full click.


  • Moderators

    Try without the local event loop, it might be that the event is processed in the parent event loop, while you're still waiting on msgBox.exec();.

  • @kshegunov Thank you for your interest. In the slot function there is log output, so I know that it's never called in any thread.

  • @Peer-Schneider Thank you. This is a funny idea. To test it I closed message box by timer without a manual action. Unfortunately, with the same negative resu

  • Lifetime Qt Champion

    @alexzh I think what @kshegunov means is: use instead of msg.exec().

  • @alexzh From the docu to QAbstractButton::clicked: "This signal is emitted when the button is activated (i.e., pressed down then released while the mouse cursor is inside the button), ..."
    I still think that this requirement of pressed down then released WHILE the mouse cursor is inside the button is not fulfilled (maybe due to the fact that the button lost focus inbetween). For a test try to use QAbstractButton::pressed instead of clicked. This emits the signal on mouse press. This is not a solution as it changes expected behaviour but it can show where the problem lays.

  • @Peer-Schneider I guess you are right. Using pressed() instead of click() solves the mystery. Thank you.
    Interesting that using release() does not work until user clicks mouse somewhere outside the button.
    That's understandable. After message box is closed, the button is still active and it still has focus, so to execute release() we must leave the button.

Log in to reply