2016-08-12 43 views
1

我有一个带参数的函数列表。对于每个参数,我都会创建一个保持其值的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类,但没有解决我的问题。

回答

1

要扩大维基王的回答,请使用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 
    } 
} 
+0

它不编译'QDoubleSpinBox *纺纱器= qobject_cast (的QObject ::发送者());'给我的错误'错误:不能在initialization' –

+0

@MatthiasPospiech糟糕 'QDoubleSpinBox' 转换为 'QDoubleSpinBox *'。这应该是''。我也修复了答案。 –

3

我会用一个小的λ为

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。

+0

你能否提供一个更详细的lambda示例? func仅在定义连接的函数中可用。此外,参数只在那里已知。我不明白这应该如何工作。 –

+0

@Matthias“func”是一个**函数对象**,它是在lambda表达式的帮助下创建的。它具有存储在** lambda capture-list **中的所有必要参数,并且'connect()'方法将其复制以供以后调用。我希望这对你有意义。 – Tomas

+0

只是一个注释:而不是'auto func = ...'它也可以'std :: function func = ...' – Tomas

1

您可以使用QObject::sender()来获取插槽功能中的主叫方旋转盒。

QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox *>(QObject::sender()); 
+1

注意:'qobject_cast'是比较安全和首选的。 –