Подключение сигналов от виджетов в QVector - PullRequest
0 голосов
/ 28 ноября 2018

Я работаю над следующим окном с 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 channel.Но тогда соединение не работает.Поэтому я попытался обойти это с QMapper.Но это не кажется хорошим вариантом для меня, и я действительно не запустил его.

Я был бы очень признателен, если бы кто-нибудь мог мне здесь помочь или хотя бы указать мне верное направление.

Ура.

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Реализуйте его с помощью лямбда-функции в вашем соединении

  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.
    }
}
0 голосов
/ 29 ноября 2018

Вы также можете просто сделать 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:

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

или вы можете вызвать connect в конструкторе myUI:

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

Iдумаю, это было бы намного проще и интуитивно понятнее, потому что ваш объект отвечает за установку своих собственных членов, и вам не нужно запоминать какие-либо индексы.

0 голосов
/ 28 ноября 2018

Если я правильно понял, в вашем методе SLOT вы можете вызвать sender (), чтобы получить объект, который испустил сигнал.Вы можете сравнить в цикле spinBox каждого из ваших inputBox, чтобы выяснить, что заставило 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();
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...