Qt - 连接动态创建的小部件的信号

时间:2016-08-12 08:16:06

标签: qt signals-slots

我有一个带参数的函数列表。对于每个参数,我创建一个保存其值的spinbox。一些函数具有零参数,其他函数具有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类,但没有找到解决我问题的方法。

3 个答案:

答案 0 :(得分:3)

我会使用一个小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。

答案 1 :(得分:1)

您可以使用QObject::sender()在插槽功能中获取调用者旋转框。

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

答案 2 :(得分:1)

要扩展Wiki Wang的答案,请使用sender()qobject_cast和spinbox对象名称的组合:

在您的代码中:

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
    }
}