Qt - 动态创建窗口小部件的连接信号
问题描述:
我有一个带参数的函数列表。对于每个参数,我都会创建一个保持其值的spinbox。一些函数具有零参数,其他函数具有n> 1个参数。Qt - 动态创建窗口小部件的连接信号
的代码看起来像这样(简体)
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类,但没有解决我的问题。
答
要扩大维基王的回答,请使用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
}
}
答
我会用一个小的λ为
auto func = [i, valueName, this](double value){
OnAmplitudeParameterChanged(i, valueName, value);
};
QObject::connect(spinbox, &QDoubleSpinBox::valueChanged, func);
编辑
乔恩·哈珀的回答启发我用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());
+1
注意:'qobject_cast'是比较安全和首选的。 –
它不编译'QDoubleSpinBox *纺纱器= qobject_cast(的QObject ::发送者());'给我的错误'错误:不能在initialization' –
@MatthiasPospiech糟糕 'QDoubleSpinBox' 转换为 'QDoubleSpinBox *'。这应该是''。我也修复了答案。 –