How to pass variables to slot methods in QT?
Solution 1
For strings and integers, you can use QSignalMapper. In your Messenger class, you would add a QSignalMapper mapper object, and your function would look like:
void Messenger::addToActivePanels(std::string& channel)
{
activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents"));
pushButton = new QPushButton(activePanelsContents);
// ...
connect(pushButton, SIGNAL(clicked()), &mapper, SLOT(map()));
mapper.setMapping(pushButton, QString(channel.c_str()));
}
and after you have added all channels to your active panels, you call
connect(&mapper, SIGNAL(mapped(const QString &)), this, SLOT(switchTab(const QString &)));
Solution 2
Use QSignalMapper to pass variables;
QSignalMapper* signalMapper = new QSignalMapper (this) ;
QPushButton *button = new QPushButton();
signalMapper -> setMapping (button, <data>) ;
connect (signalMapper, SIGNAL(mapped(QString)), this,
SLOT(buttonClicked(QString))) ;
in slot i.e
void class::buttonClicked(QString data){
//use data
// to get sender
QSignalMapper *temp = (QSignalMapper *)this->sender();
QPushButton *btn = (QPushButton *)temp->mapping(data);
// use btn
}
Hope my ans may help you
Solution 3
Don't use the sender method unless you absolutely have to. It ties the function directly to being used only as a slot (can't be called directly). Retain the behavior of having the function accept a string and simply make a mechanism by which you can call it.
One method, among others you might find, is to leverage use of QSignalMapper. It will map objects to values and regenerate signals of the appropriate signature.
Solution 4
I would do it with "relay" objects:
Create TabSwitchRelay which is a sub-class of QObject with this constructor:
TabSwitchRelay::TabSwitchRelay(QObject *parent, Messanger * m, const QString & c)
: QObject(parent), m_messanger(m), m_channel(c)
{
}
It also has a slot clicked():
void TabSwitchRelay::clicked()
{
m_messager->switchTab(m_channel);
}
Now replace the line in your code that does connect with this:
TabSwitchRelay * tabRelay = new TabSwitchRelay(pushButton, this, channel);
connect(pushButton, SIGNAL(clicked()), tabRelay, SLOT(clicked()));
It's not tested but you get teh basic idea.
Related videos on Youtube
Neko
Updated on May 19, 2022Comments
-
Neko about 1 yearI'm making a little chat messenger program, which needs a list of chat channels the user has joined. To represent this list graphically, I have made a list of
QPushButtons, which all represent a different channel. These buttons are made with the following method, and that's where my problem kicks in:void Messenger::addToActivePanels(std::string& channel) { activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents")); pushButton = new QPushButton(activePanelsContents); pushButton->setObjectName("pushButton"); pushButton->setGeometry(QRect(0, 0, 60, 60)); pushButton->setText(""); pushButton->setToolTip(QString(channel.c_str())); pushButton->setCheckable(true); pushButton->setChecked(false); connect(pushButton, SIGNAL(clicked()), this, SLOT(switchTab(channel))); }(activePanelContents is a QWidget that holds the list.)
The point is that each button should call the
switchTab(string& tabname)method when clicked, including the specific channel's name as variable. This implementation doesn't work though, and I haven't been able to find out how to properly do this. -
Patrice Bernassola over 12 yearsBe aware of the warnings before using the QObject::sender in your code -
Neko over 12 yearsThis doesn't seem to work... switchTab() simply never gets called, although no errors are given anywhere at all. -
Daniel Gallagher over 12 yearsDoesswitchTab()take aconst QString &? If it doesn't, you need to change it so it does. Qt doesn't allow you to passstd::string(or, in general, any type not registered withqRegisterMetaType) through signals and slots. Typos insideSIGNALandSLOTare not detected until runtime, because those macros turn their arguments into strings. Chances are Qt is printing an error message to the console when it tries to make the connection toswitchTab(const QString &). -
fkl over 10 yearsThanks for this answer. I was using QSignalMapper with QTNetworkRequest and didn't know i had to use Mapper->mapping(data) to obtain the object in such a case. I was simply using qobject_cast<QObject*>(sender) which only works when you have no parameter. -
parsecer about 7 yearsNot sure why your post was minused, but thanks anyway. You helped a lot