Search code examples
qtdynamicsignals-slots

Qt: dynamic widgets signal and slot connection


In my Qt app, I create some of my widgets dynamically. Among them are QToolButtons that need to have a similar behavior.

Here is how the widgets are created:

QMap<QString, QToolButton*> unselectButtonMap;
foreach(QString instance, ...) {
  unselectButtonMap[instance] = new QToolButton;
  myLayout->addWidget(unselectButtonMap[instance]);
  QObject::connect(unselectButtonMap[instance],SIGNAL(clicked()),this,SLOT(unselectInstance()));
}

Now I would like the unselectInstence slot to know which instance is concerned.

I first thougth about giving the instance name as a parameter to the slot, but slots only take parameters from signals. The idea was something like:

QObject::connect(unselectButtonMap[instance],SIGNAL(clicked()),this,SLOT(unselectInstance(instance)));

Any other idea on how to do that ?

Notes: I'm using Qt4.8

EDIT: based on shan's answer, and because I needed the instance name instead of the QToolButton itself, here is what I came up to

void MyWindow::unselectInstance() {
  foreach(QString instance, unselectButtonMap.keys()) {
    if(unselectButtonMap[instance] == QObject::sender()) {
      //do stuff here...
    }
  }
}

The pointer comparison seems to work pretty well.

RE-EDIT: and based on user1313312's answer, we would declare a QSignalMapper:

QSignalMapper *signalMapper = new QSignalMapper(this);
QObject::connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(unselectInstance(QString)));

then connect the QToolButton to the mapper

signalMapper->setMapping(unselectButtonMap[instance], instance);
QObject::connect(unselectButtonMap[instance],SIGNAL(clicked()),signalMapper,SLOT(map()));

and the slot would be way much simpler:

void MyWindow::unselectinstance(QString instance) {
  //do stuff here...
}

Solution

  • Although using QObject::sender() is perfectly fine, the idealistic approach would be QSignalMapper