For two days now I've been trying to understand why different slots are being called by the same button on my application. I've googled a lot about the subject but mostly what I found was regarding a unique SLOT being called multiple times by the same button which is solved adding a fifth parameter Qt::UniqueConnection
on connect call
i.e.:
connect(obj, SIGNAL(signal()), obj2, SLOT(slot()), Qt::UniqueConnection);
Moving on, my problem is that a same button is calling different slots when it shouldn't. I created a generic code to setup all my buttons:
void KHUB::btSetupInt(QPushButton **button, const QString name, int posX, int posY, int width, int height, void (KHUB::*fptr)(int parameter), int value, int handler) {
*button = new QPushButton(name, this);
(*button)->setGeometry(QRect(QPoint(posX, posY), QSize(width, height)));
signalMapper->setMapping(*button, value);
connect(*button, SIGNAL(clicked()), signalMapper, SLOT(map()));
//qDebug() << "My value: " + QString::number(value);
switch (handler) {
case (int) ButtonHandler::hl_Register:
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleRegister(int)), Qt::UniqueConnection);
break;
case (int)ButtonHandler::hl_UpVote:
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleUpVote(int)), Qt::UniqueConnection);
break;
case (int) ButtonHandler::hl_OpenUrl:
//connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleUrl(int)), Qt::UniqueConnection);
break;
case (int)ButtonHandler::hl_DownVote:
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleDownVote(int)), Qt::UniqueConnection);
break;
case (int) ButtonHandler::hl_DisposeBrowser:
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleDispose(int)), Qt::UniqueConnection);
break;
}
}
Within it I have my signalMapper
which is declared in my header file. This button setup is being called by:
void KHUB::handleSearch() {
//DO THE MATH
for (int pos = 0; pos < localUrl.size(); pos++){
QLabel *link = new QLabel();
link->setText("<a href=\"" + localUrl.at(pos) + "\">" + localUrl.at(pos) + "</a>");
link->setTextFormat(Qt::RichText);
link->setTextInteractionFlags(Qt::TextBrowserInteraction);
link->setOpenExternalLinks(true);
QPushButton *upArrow = new QPushButton();
btSetupInt(&upArrow, "Up Vote", 225, 300, 100, 25, &KHUB::handleUpVote, pos*147, (int)ButtonHandler::hl_UpVote);
QPushButton *open = new QPushButton("Open");
//btSetupInt(&open, "Open", 225, 300, 100, 25, &KHUB::handleUrl, pos, (int) ButtonHandler::hl_OpenUrl);
QPushButton *downArrow = new QPushButton();
btSetupInt(&downArrow, "Down Vote", 225, 300, 100, 25, &KHUB::handleDownVote, pos*163, (int)ButtonHandler::hl_DownVote);
QLabel *separator = new QLabel();
QLabel *guider = new QLabel("<----------------------------------------------------------------------------------------------------------------------------------------------------->");
gridLayout->addWidget(link, componentsPos, 0, 1, -1);
gridLayout->addWidget(guider, componentsPos, 1, 1, -1);
gridLayout->addWidget(upArrow, componentsPos - 1, 2, 1, 1, Qt::AlignBottom);
gridLayout->addWidget(open, componentsPos, 2, 1, 1);
gridLayout->addWidget(downArrow, componentsPos + 1, 2, 1, 1, Qt::AlignTop);
gridLayout->addWidget(separator, componentsPos + 2, 1, 1, 1);
componentsPos = componentsPos + 5;
}
//KEEP DOING THE MATH
}
Commented lines are as it is for debugging purposes. Anyway, this code was fully working when I had only the open
QPushButton. When added upVote
and downVote
I expected the programm to replicate its logic success, instead, now when I click for Up voting ou Down voting the programm triggers both slots for handling Up and Down votin and also "Open" if not commented. Code for handling Up and Down Vote:
void KHUB::handleUpVote(int reference) {
qDebug() << "This is my reference for upvoting: " + QString::number(reference/147);
}
void KHUB::handleDownVote(int reference) {
qDebug() << "This is my reference for DOWNVOTING: " + QString::number(reference/163);
}
According to Qt QSignalMapper documentation (Topic "Advanced Signals and Slots Usage" at page's ending) I'm doing everything as expected. You also must have noticed that I multiplied
pos
at btSetupInt
call by 147 and 163 (to produce a "random" number) since every button must have its only integer ID [see setMapping for integers void QSignalMapper::setMapping(QObject * sender, int id)
].
Days ago I was using the same position (pos
) for the three of them (buttons) and whether multiplying or not the produced result is equal. That leads me to my first question: This ID is a unique identifier for each button or a unique parameter that can be passed by the button? I Still didn't get this considering the context I gave above
This is my UI:
This is my output clicking (random link choosen) Up Vote at us.battle.net/wow/en/blog/19913791/patch-623-preview-10-14-2015:
"This is my reference for upvoting: 3"
"This is my reference for DOWNVOTING: 3"
This is my output clicking (random link choosen) Down Vote at http://www.swtor.com/holonet/companions/blizz:
"This is my reference for upvoting: 6"
"This is my reference for DOWNVOTING: 6"
I used breakpoints to see if the handler
switch at btSetupInt
was being called correctly and it is. Even not using my member function btSetupInt
to call connections I'm still getting the same wrong results. To finish, my second and main question: How is even possible, in the given context, that a same button is calling different slots? What am I missing here?