Qt - 连接动态创建的小部件的信号
Qt - connect signals of dynamical created widgets
我有一个带参数的函数列表。对于每个参数,我都创建了一个保存其值的旋转框。有些函数的参数为零,有些函数的参数为 n>1。
代码看起来像这样(简化)
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
}
但是插槽需要知道调用了哪些小部件、参数名称及其值。然而,该信号仅提供一个值。
插槽看起来像这样
OnAmplitudeParameterChanged(int index, QString name, double value)
这在 Qt 中是如何解决的?我找到了 QSignalMapper class,但没有找到它如何解决我的问题。
我会为此使用一点 lambda
auto func = [i, valueName, this](double value){
OnAmplitudeParameterChanged(i, valueName, value);
};
QObject::connect(spinbox, &QDoubleSpinBox::valueChanged, func);
编辑
Jon Harper 的回答启发我使用 QObject::setProperty()
作为另一个有趣的解决方案:
QDoubleSpinBox* spinbox = new QDoubleSpinBox();
spinbox->setProperty("myindex", i);
spinbox->setProperty("myname", valueName);
然后在你的位置:
void SomeClass::OnAmplitudeParameterChanged(double value)
{
int index = sender()->property("myindex").toInt();
QString name = sender()->property("myname").toString();
}
但无论如何,我可能还是会使用 lambda。
您可以使用QObject::sender()在插槽函数中获取调用者旋转框。
QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox *>(QObject::sender());
要扩展 Wiki Wang 的答案,请结合使用 sender()
、qobject_cast
和旋转框的对象名称:
在您的代码中:
QString valueName = parameterList().at(i);
double value = parameter(valueName);
QDoubleSpinBox * spinbox = new QDoubleSpinBox();
spinbox->setObjectName(valueName);
然后在插槽中:
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
}
}
我有一个带参数的函数列表。对于每个参数,我都创建了一个保存其值的旋转框。有些函数的参数为零,有些函数的参数为 n>1。
代码看起来像这样(简化)
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
}
但是插槽需要知道调用了哪些小部件、参数名称及其值。然而,该信号仅提供一个值。
插槽看起来像这样
OnAmplitudeParameterChanged(int index, QString name, double value)
这在 Qt 中是如何解决的?我找到了 QSignalMapper class,但没有找到它如何解决我的问题。
我会为此使用一点 lambda
auto func = [i, valueName, this](double value){
OnAmplitudeParameterChanged(i, valueName, value);
};
QObject::connect(spinbox, &QDoubleSpinBox::valueChanged, func);
编辑
Jon Harper 的回答启发我使用 QObject::setProperty()
作为另一个有趣的解决方案:
QDoubleSpinBox* spinbox = new QDoubleSpinBox();
spinbox->setProperty("myindex", i);
spinbox->setProperty("myname", valueName);
然后在你的位置:
void SomeClass::OnAmplitudeParameterChanged(double value)
{
int index = sender()->property("myindex").toInt();
QString name = sender()->property("myname").toString();
}
但无论如何,我可能还是会使用 lambda。
您可以使用QObject::sender()在插槽函数中获取调用者旋转框。
QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox *>(QObject::sender());
要扩展 Wiki Wang 的答案,请结合使用 sender()
、qobject_cast
和旋转框的对象名称:
在您的代码中:
QString valueName = parameterList().at(i);
double value = parameter(valueName);
QDoubleSpinBox * spinbox = new QDoubleSpinBox();
spinbox->setObjectName(valueName);
然后在插槽中:
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
}
}