如何使自定义小部件内的子小部件的信号可连接?
How to make the signals of child widgets inside a custom widget connectable?
我认为我对一个对我来说似乎很基础的概念有一些重大问题。
我创建了一个自定义小部件,它实际上只是一小部分小部件,因此会出现多次。
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;
};
然后在 gui 中使用此自定义小部件。当然,我希望这个 gui 对旋转框值的变化做出反应。据我了解,我可以
1) 为QSpinBox
es提供getter,并将它们的信号连接到class之外。
2) "Re-route" 他们的信号如下例所示
@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 class 中 connect(customwidget,SIGNAL(spinboxAValueChanged(int),this,SLOT(doSomething(int)));
尤其是版本 2) 看起来非常混乱并且...我在问自己 - 如何连接到自定义小部件内的小部件信号?
一个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"
我认为我对一个对我来说似乎很基础的概念有一些重大问题。
我创建了一个自定义小部件,它实际上只是一小部分小部件,因此会出现多次。
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;
};
然后在 gui 中使用此自定义小部件。当然,我希望这个 gui 对旋转框值的变化做出反应。据我了解,我可以
1) 为QSpinBox
es提供getter,并将它们的信号连接到class之外。
2) "Re-route" 他们的信号如下例所示
@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 class 中 connect(customwidget,SIGNAL(spinboxAValueChanged(int),this,SLOT(doSomething(int)));
尤其是版本 2) 看起来非常混乱并且...我在问自己 - 如何连接到自定义小部件内的小部件信号?
一个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"