2016-08-12 44 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'是比較安全和首選的。 –