连接来自QVector中的小部件的信号

时间:2018-11-28 15:44:29

标签: qt qt5

我正在使用QT在以下窗口中工作:

enter image description here

对于我的行,我具有以下结构:

typedef struct
{
    struct{
        int x;
        int y;
        int width;
        int height;
        int layer;
        int idx;
    }outputSettings;

    QDoubleSpinBox *xSpinBox;
    QDoubleSpinBox *ySpinBox;
    QDoubleSpinBox *heightSpinBox;
    QDoubleSpinBox *widthSpinBox;
    QDoubleSpinBox *layerSpinBox;

    // Checkboxes
    QCheckBox *channelCheckBox;
}myUI;

QVector<myUI> inputBoxes;   // Create a row of input boxes per channel

然后在for循环中创建它们:

for(i = 0; i < inputChannels; ++i)
{
    inputBoxes[i].channelCheckBox = new QCheckBox;
    inputBoxes[i].channelCheckBox->setChecked(true);

    inputBoxes[i].xSpinBox = new QDoubleSpinBox;
    inputBoxes[i].xSpinBox->setRange(minXPos, maxXPos);
    inputBoxes[i].xSpinBox->setSingleStep(1);
    inputBoxes[i].xSpinBox->setValue(0);
    inputBoxes[i].xSpinBox->setDecimals(0);
    connect(inputBoxes[i].xSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setXValue(double)));

    inputBoxes[i].ySpinBox = new QDoubleSpinBox;
    inputBoxes[i].ySpinBox->setRange(minYPos, maxYPos);
    inputBoxes[i].ySpinBox->setSingleStep(1);
    inputBoxes[i].ySpinBox->setValue(0);
    inputBoxes[i].ySpinBox->setDecimals(0);
    connect(inputBoxes[i].ySpinBox, SIGNAL(valueChanged(double)), this, SLOT(setYValue(double)));

...

现在,我被卡住了。我想将我的旋转框的valueChanged属性连接到outputSettings结构。该结构体将是我最后的返回类型。 我实现了以下插槽:

public slots:
void setXValue(double x){inputBoxes[0].outputSettings.x = int(x);}
void setYValue(double y){inputBoxes[0].outputSettings.y = int(y);}

...

但是在这里,我不知道什么向量项称为函数。 (当前我刚刚输入inputBoxes [0]作为虚拟对象) 我的第一个想法是添加一个额外的参数int通道。但是然后连接不起作用。因此,我尝试使用QMapper解决该问题。但这对我来说似乎不是一个好选择,我也没有真正让它运行。

如果有人可以在这里帮助我,或者至少将我指出正确的方向,我将不胜感激。

干杯。

3 个答案:

答案 0 :(得分:2)

通过在连接中使用lambda函数来实现它

  connect(inputBoxes[i], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
            [i](double value)
    {
        // use i as your vector index here 
        handleDoubleSpinBoxChanged(i, value);
    });

然后您可以将广告位功能更改为

void handleDoubleSpinBoxChanged(int i, double value)
{
   inputBoxes[i].outputSettings.x = int(x);
}

第二个选项是从发件人对象获取旋转框索引 您将必须先将其存储在循环中

inputBoxes[i].xSpinBox->setProperty("index",i);

那你就可以得到

void MainWindow::setXValue(double d)
{
    QDoubleSpinBox * sb = qobject_cast<QDoubleSpinBox *>(QObject::sender());
    int iCallerVectorIndex = -1;

    if (sb != Q_NULLPTR)
    {
        iCallerVectorIndex = sb->property("index").toInt(); // to get the caller index.
    }
}

答案 1 :(得分:0)

如果我对,请在您的SLOT方法中调用sender()来检索发出信号的对象。您可以循环比较每个inputBox的spinBox,以找出导致SLOT执行的原因,例如:

// in your SLOT method:
for (int i = 0; i < inputChannels; i++){
  if (inputBoxes[i].xSpinBox == (QDoubleSpinBox *)sender()){
    // the xSpinBox of the i-th inputBox emitted the signal
    break();
  }
}

答案 2 :(得分:0)

您也可以将myUI设为QObject并在其中添加插槽功能。 然后,您将不需要任何索引。

typedef struct
{
    Q_OBJECT
    struct{
        int x;
        int y;
        int width;
        int height;
        int layer;
        int idx;
    }outputSettings;

    QDoubleSpinBox *xSpinBox;
    QDoubleSpinBox *ySpinBox;
    QDoubleSpinBox *heightSpinBox;
    QDoubleSpinBox *widthSpinBox;
    QDoubleSpinBox *layerSpinBox;

    // Checkboxes
    QCheckBox *channelCheckBox;
public slots:
setXValue(double);
setYValue(double);
}myUI;

连接呼叫示例:

 connect(inputBoxes[i].ySpinBox, SIGNAL(valueChanged(double)), inputBoxes[i], SLOT(setYValue(double))

或者您可以在myUI的构造函数中调用connect:

myUI() {
    connect(xSpinBox, SIGNAL(valueChanged(double)), 
        this, SLOT(setXValue(double))
    connect(ySpinBox, SIGNAL(valueChanged(double)), 
        this, SLOT(setYValue(double))
}

我认为这将更加简单和直观,因为您的对象负责设置自己的成员,并且您无需记住任何索引。