Valentine Chido Nwachukwu Valentine Chido Nwachukwu - 1 month ago 13
C++ Question

Passing parameters from QtMessageBox signals to buttonClick signal Handler slot

I am trying to create a popup that will (1) be non-modal, (2) carry context data that will be handled later when the user clicks the ok event. So far I have the code below which does pop up as a non-modal. I know that

msgBox->open(this, SLOT(msgBoxClosed(QAbstractButton *))
and
msgBoxClosed(QAbstractButton *button)
work but when I added the
QStringList collisionSections
to the SLOT parameter. I get this error:

QObject::connect: No such slot MainWindow::msgBoxClosed(QAbstractButton *, collisionSections) in src\mainwindow.cpp:272
QObject::connect: (receiver name: 'MainWindow')


which I understand because it is declaring the SLOT there, but I don't know how to go about doing what I want which is passing in the QString as contents to my signal and have it play well with the buttonClicked() event that qmessagebox throws on the OK click. I could also be approaching this the wrong way, please let me know if so. Any help is much appreciated!

void MainWindow::do_showCollisionEvt(QStringList collisionSections)
{
QString info = "Resolve sections";

for (QString section : collisionSections)
{
if (!section.isEmpty())
{
info.append(" [" + section + "] ");
qDebug() << "Emitting node off for:" << section;
emit nodeOff(section);
}

}

QMessageBox *msgBox = new QMessageBox;
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setText("Collision event detected!");
msgBox->setInformativeText(info);
msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->setDefaultButton(QMessageBox::Ok);
msgBox->setModal(false);
msgBox->open(this, SLOT(msgBoxClosed(QAbstractButton *, collisionSections)));
}


void MainWindow::msgBoxClosed(QAbstractButton *button, QStringList collisionSections) {

QMessageBox *msgBox = (QMessageBox *)sender();
QMessageBox::StandardButton btn = msgBox->standardButton(button);
if (btn == QMessageBox::Ok)
{
for (QString section : collisionSections)
{
if (!section.isEmpty())
{
qDebug() << "Emitting nodeON for:" << section;
emit nodeOn(section);
}
}
}
else
{
throw "unknown button";
}
}

Answer

First of all, the open() connects your slot to the finished() singnal with no arguments or to buttonClicked() signal if first slot argument is pointer (your case).

Second. you are not correctly passing param. You can't do it during declaration, the parameters that slot recieves are set in signal emission, which in your case you can't control. In SLOT you could only declare the arguments TYPES not their values (note the SLOT is just a macro, in reality result of SLOT(...) is just a string (char*)).

I suggest you to use the setProperty() method on message box, e.g.:

msgBox->setModal(false);
msgBox->setProperty("collisionSections", collisionSections);
msgBox->open(this, SLOT(msgBoxClosed(QAbstractButton *)));

And your slot could look like then:

void MainWindow::msgBoxClosed(QAbstractButton *button, QStringList collisionSections) {
    QMessageBox *msgBox = (QMessageBox *)sender();
    QStringList collisionSections = msgBox->property("collisionSections").toStringList();