Reputation: 3494
I have a list of functions with parameters. For each parameter I create a spinbox holding its value. Some functions have zero parameters others have n>1 parameters.
The code looks like this (simplified)
for (int i = 0; i < parameterList.size(); ++i) {
QString valueName = parameterList().at(i);
double value = parameter(valueName);
QDoubleSpinBox * spinbox = new QDoubleSpinBox();
QLabel * label = new QLabel();
label->setText(valueName);
spinbox->setValue(value);
// does NOT work, Slot need three parameters!
QObject::connect(spinbox, &QDoubleSpinBox::valueChanged,
this, &OnAmplitudeParameterChanged);
... add widgets to layout
}
However the slot needs to know which widgets was calling, the parameter name and its value. The signal however provides only a value.
The slot looks like this
OnAmplitudeParameterChanged(int index, QString name, double value)
How is this solved in Qt? I found a QSignalMapper class but not how this would solve my problem.
Upvotes: 1
Views: 321
Reputation: 4347
To expand on Wiki Wang's answer, use the combination of sender()
, qobject_cast
and the spinbox's object name:
In your code:
QString valueName = parameterList().at(i);
double value = parameter(valueName);
QDoubleSpinBox * spinbox = new QDoubleSpinBox();
spinbox->setObjectName(valueName);
Then in the slot:
void SomeClass::OnAmplitudeParameterChanged(double value)
{
QDoubleSpinBox *spinbox = qobject_cast<QDoubleSpinBox *>(sender());
if (spinbox && parameterList.contains(spinbox->objectName()) {
int value = parameter(spinbox->objectName());
// your code here
}
}
Upvotes: 1
Reputation: 2210
I would use a little lambda for that
auto func = [i, valueName, this](double value){
OnAmplitudeParameterChanged(i, valueName, value);
};
QObject::connect(spinbox, &QDoubleSpinBox::valueChanged, func);
EDIT
Jon Harper's answer inspired me to use the QObject::setProperty()
as another interesting solution:
QDoubleSpinBox* spinbox = new QDoubleSpinBox();
spinbox->setProperty("myindex", i);
spinbox->setProperty("myname", valueName);
and then in your slot:
void SomeClass::OnAmplitudeParameterChanged(double value)
{
int index = sender()->property("myindex").toInt();
QString name = sender()->property("myname").toString();
}
But still, I would probably use the lambda anyway.
Upvotes: 3
Reputation: 698
You can use QObject::sender() to get the caller spinbox in the slot function.
QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox *>(QObject::sender());
Upvotes: 1