Search code examples
qtslotqmessageboxqradiobutton

Qt: Issuing a message before emitting a signal


Brief description of my application and my question:

In a QTabWidget I have several groupBoxes containing each 2 QRadioButtons. E.g. Select Menu (groupBox): (RadioButton:) A (RadioButton:) B

At one point of time, only one Menu can be active. Both radioButtons are connected to each othe -> When I click radioButton A and set it true, radioButton B is automatically set false - and the other way round.

When trying to change the menu setting, before a click signal is emitted, I would like to issue a QMessageBox Warning "Are you sure you want to change the menu? This can cause severe damage to your device." -Yes/No.

When clicking Yes, I would like to change the menue setting. When clicking No, I would like everything to remain as before.

The only problem I have is: When issuing the QMessageBox in the on_radio_button_toggled slot, the radioButton state has already changed to true. Even if I change the state in the slot again and correct them, it looks like the state has already changed when the pop up message shows up. I don't want that because that implies that the state of the menue has already changed.

Where or How can I let a QMessageBox pop up before emitting the actual signal slot - when clicking the radio Button?

Thank you very much for your help.

Update: I have now implemented an eventFilter as recommended. Here is my source code:

ui->radioButtonMenu1->installEventFilter(this);
ui->radioButtonMenu2->installEventFilter(this);

SubmenuOne is a QWidget. It is integrated into the MainWindow by a QTabWidget (via placeholder).

bool SubmenuOne::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMessageBox::StandardButton reply;
reply= QMessageBox::question(this,tr("WARNING"),tr("Changing the settings   may cause severe damage to your device! Please confirm your decision."),QMessageBox::Yes|QMessageBox::No);

if (reply == QMessageBox::Yes)
{

//QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
   //keyEvent->accept();
   //event->accept();
   qDebug("Yes.");
    return false;
}
else
{
    qDebug("No.");

     return true;
}

}
}

Solution

  • You have to use bool eventFilter(QObject *obj, QEvent *event); Declare event filter in your window, then instal event filter to every radiobutton like this: radioButton1->installEventFilter(this);. Then at eventFilter check event type: if (event->type() == QEvent::MouseButtonPress) and show your QMessageBox. Then you can accept event and return true or false depending on user choise.

    bool SubmenuOne::eventFilter(QObject *obj, QEvent *event)
    {
      if(event->type() == QEvent::MouseButtonPress)
      {
        QMessageBox::StandardButton reply;
        reply= QMessageBox::question(this,tr("WARNING"),tr("Changing the settings   may cause severe damage to your device! Please confirm your decision."),QMessageBox::Yes|QMessageBox::No);
    
        if (reply == QMessageBox::Yes)
        {
            static_cast<QRadioButton*>(obj)->setChecked(True);
        }
        event->accepted();
        return true;
      }
      return QMainWindow::eventFilter(obj, event); //you forget this. QMainWindow is just base class of your SubmenuOne.
    }