Как сделать так, чтобы сигналы дочерних виджетов внутри настраиваемого виджета были подключаемыми? - PullRequest
0 голосов
/ 09 сентября 2018

Мне кажется, у меня есть какая-то серьезная проблема с концепцией, которая мне кажется довольно простой.

Я создал собственный виджет, который на самом деле представляет собой небольшую коллекцию виджетов, которая, как таковая, будет появляться несколько раз.

class CustomWidget : public QWidget {
    Q_OBJECT
public:
    explicit CustomWidget(QWidget parent=nullptr) : QWidget(parent) {
        spinboxA = new QSpinBox;
        spinboxB = new QSpinBox;
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout.addWidget(spinboxA);
        layout.addWidget(spinboxB);
        this->setLayout(layout);
    }
private:
    QSpinBox* spinboxA;
    QSpinBox* spinboxB;
};

Этот пользовательский виджет затем используется внутри графического интерфейса. Конечно, я хочу, чтобы этот интерфейс реагировал на изменения стоимости спинбоксов. В моем понимании я могу либо

1) Предоставьте геттер для QSpinBox es и подключите их сигналы вне класса. 2) «Перенаправить» их сигналы, как в примере ниже

@ 1) используется через connect(customwidget->getSpinboxA(),SIGNAL(valueChanged(int)),this,SLOT(doSomething(int)));, наверное?

@ 2)

class CustomWidget : public QWidget {
    Q_OBJECT
public:
    explicit CustomWidget(QWidget parent=nullptr) : QWidget(parent) {
        spinboxA = new QSpinBox;
        spinboxB = new QSpinBox;
        QHBoxLayout* layout = new QHBoxLayout;
        layout.addWidget(spinboxA);
        layout.addWidget(spinboxB);
        this->setLayout(layout);
        connect(spinboxA,SIGNAL(valueChanged(int)),//...
            this,SLOT(onSpinboxAValueChanged(int)));
    }
private:
    QSpinBox* spinboxA;
    QSpinBox* spinboxB;
private slots:
    void onSpinboxAValueChanged(int x) {emit spinboxAValueChanged(x);}
    //...
signals:
    void spinboxAValueChanged(int x)
};

В классе GUI можно было бы connect(customwidget,SIGNAL(spinboxAValueChanged(int),this,SLOT(doSomething(int)));

Особенно версия 2) кажется очень загроможденной и ... Я спрашиваю себя - как мне подключиться к сигналам виджетов внутри моего пользовательского виджета?

1 Ответ

0 голосов
/ 09 сентября 2018

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

#include <QApplication>
#include <QHBoxLayout>
#include <QSpinBox>
#include <QWidget>

#include <QDebug>

class CustomWidget : public QWidget {
    Q_OBJECT
public:
    explicit CustomWidget(QWidget *parent =nullptr):
        QWidget(parent),
        spinboxA(new QSpinBox),
        spinboxB(new QSpinBox)
    {
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->addWidget(spinboxA);
        layout->addWidget(spinboxB);
        connect(spinboxA, QOverload<int>::of(&QSpinBox::valueChanged), this, &CustomWidget::spinboxAValueChanged);
        connect(spinboxB, QOverload<int>::of(&QSpinBox::valueChanged), this, &CustomWidget::spinboxBValueChanged);
        // old syntax:
        // connect(spinboxA, SIGNAL(valueChanged(int)), this, SIGNAL(spinboxAValueChanged(int)));
        // connect(spinboxB, SIGNAL(valueChanged(int)), this, SIGNAL(spinboxBValueChanged(int)));
    }
private:
    QSpinBox *spinboxA;
    QSpinBox *spinboxB;
signals:
    void spinboxAValueChanged(int x);
    void spinboxBValueChanged(int x);
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CustomWidget w;

    QObject::connect(&w, &CustomWidget::spinboxAValueChanged, [](int i){
       qDebug()<< "spinboxAValueChanged: "<< i;
    });
    QObject::connect(&w, &CustomWidget::spinboxBValueChanged, [](int i){
       qDebug()<< "spinboxBValueChanged: "<< i;
    });

    w.show();

    return a.exec();
}

#include "main.moc"
...