I have a function that receives a QList of a class I created. Let's call this hypothetical class "Stuff". So, this function receives a QList of Stuff
I iterate through the QList, and depending on the properties of the "Stuff" object, I will generate one of the following:
1) QLineEdit
2) QCheckBox
3) QComboBox
This isn't the actual code, but this is what I'm essentially doing:
void MyProgram::update(QList<Stuff> myStuffs)
{
this->mSignalMapper = new QSignalMapper();
foreach (Stuff stuff, myStuffs)
{
if (stuff.isInt())
{
QLineEdit* input = new QLineEdit();
//There is code here to setup the QLineEdit and fill an initial value
verticalLayout->addWidget(input); //verticalLayout is QVBoxLayout
QObject::connect(input, SIGNAL(editingFinished()), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
/*
* NOTE: the stuff.getMappingId() function returns an int that is unique
* to that stuff object. I'm 100% sure each stuff object is getting
* a unique mapping ID */
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
else if (stuff.isBool())
{
QCheckBox* input = new QCheckBox();
//There is code here to setup the QCheckBox and set an initial value
verticalLayout->addWidget(input);
QObject::connect(input, SIGNAL(stateChanged(int)), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
else if (stuff.isStringList())
{
QComboBox* input = new QComboBox();
//There is code here to setup the QComboBox and fill in values for the combo box
verticalLayout->addWidget(input);
QObject::connect(input, SIGNAL(activated(int)), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
}
}
The problem is that if I trigger just one of the Widget's signals, by either editing the QLineEdit, or checking the check box, or changing the combo box value, the onStuffChanged(int) function is being called N times, where N = number of mSignalMapper's mappings.
What's going on here? If I loop through and create 10 widgets, clicking on just 1 of the 10 widgets calls the function 10 times, and each of those 10 times passes the unique int associated with only the 1 object I interacted with. So, if the 1st of 10 widgets was a checkbox with a unique int ID of 27, the onStuffChanged(int) function gets called 10 times with the parameter of 27 each time.
The problem is this line:
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
You are making the same connection N times (N = your "stuff" count), so every single mapped()
signal triggers the onStuffChanged(int)
slot N times also.
Solution: Move this line outside the loop, to by called only once.