带参数的 QT 信号如何工作
How QT signals with parameters works
谁能告诉我带参数的信号究竟是如何工作的?我的意思是...如果我声明了信号 f.e.:
void sign1(int)
我应该如何指定我想用那个信号发送什么整数?另外,我可以用多个参数声明信号吗?喜欢:
void sign2(int, int)
再一次...我想用 sign2 发送我拥有的四个变量中的两个。这可能吗,应该怎么做?下面是一个更详细的例子来说明我的问题:
class Board
{
signals:
void clicked(int, int);
private:
int x1{4}; int x2{4}; int x3{5}; int x4{8};
}
并且有 board.ui 个带按钮的文件。单击按钮后,我想发送到插槽,例如 x1 和 x3。示例:
connect(ui->button, SIGNAL(clicked(int, int)), obj2, slot2);
我希望它能以某种方式清楚。非常感谢您的帮助。
QObject::connect()
像这样工作(在一般情况下,不使用 lambda):
connect(obj1, obj1_signal, obj2, ob2_slot)
由于 class QPushButton
中没有信号 clicked(int, int)
(我假设您正在使用),因此无法用于连接。
如果你想在一个按钮中有信号clicked(int, int)
,你可以subclass QPushButton
,添加信号,并使用emit
发送信号处理点击事件的地方。
但是,这不是一个好的设计,因为您必须在按钮 class 中存储一个 Board 对象(或至少是对它的引用),这与 class.
相反,您可以有一个插槽 Board::buttonClicked()
,连接到 QPushButton::clicked(bool)
。然后在那个插槽中,你可以做 emit Board::clicked(int, int)
.
signal/slot连接的规则可以表述如下:
You can ignore signal arguments, and you cannot create slot arguments from nothing
这是什么意思?
如果你的信号有一个参数,你的插槽最多也应该有一个参数。见下表。
在第一行,你有一个带有两个参数的信号,因此,你的插槽可以有两个参数(使用所有信号参数),或一个参数(忽略信号的一个参数)或无参数(忽略两个信号参数)
在第二行,您有一个带有一个参数的信号 valueChanged(int)
。您的插槽可能有一个参数或没有参数(忽略信号参数)但 可能不会 有两个
或更多参数 you cannot create values
.
在第三行,信号 textChanged(QString)
无法与 setValue(int)
连接,因为我们无法从 QString 创建 int
值。
第四行遵循这些规则。如果信号没有参数,连接的信号不能创建新参数,因此 update()
是正确的,setValue(int)
不是。
另一个需要注意的点是 signal/slot 的重载。在这种情况下,许多 signals/slots 具有相同的名称但具有不同的数字或不同类型的参数。
您可能有 class QLCDNumber
,其中插槽 display
有很多过载。在此 cas 中,您必须明确定义要按说明使用的信号槽对 here
您可以试试下面的例子:
示例:
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *window = new QWidget();
window->setAttribute(Qt::WA_DeleteOnClose);
QVBoxLayout *topLayout = new QVBoxLayout(window);
//Set up of GUI
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 100);
QSpinBox *spin = new QSpinBox;
spin->setReadOnly( true );
QHBoxLayout *horizontalLayout = new QHBoxLayout;
horizontalLayout->addWidget(slider);
horizontalLayout->addWidget(spin);
topLayout->addLayout(horizontalLayout);
// using pointer to member function
QObject::connect(slider, &QSlider::valueChanged,
spin, &QSpinBox::setValue);
// set the slider position and hence the QSpinBox value too
slider->setValue(40);
// Uncommenting the following connect will result in a compile time error.
// The signal passes no arguments whereas the slot is expecting a single
// argument.
// By using function pointers we get compile time parameter list checking.
// Using the old-style SIGNAL/SLOT macros this would have been detected
// as a run time warning only.
//QObject::connect(slider, &QSlider::sliderPressed,
// spin, &QSpinBox::setValue);
QTextEdit *textEdit = new QTextEdit();
textEdit->setAttribute(Qt::WA_DeleteOnClose);
// Uncommenting the following connect will result in a compile time error.
// The signal is passing an incompatible parameter to the slot.
// By using function pointers we get compile time parameter type conversion.
// Using the old-style SIGNAL/SLOT macros this would have been detected
// as a run time warning only.
//QObject::connect(slider, &QSlider::sliderMoved,
// textEdit, &QTextEdit::setFontFamily);
window->show();
return app.exec();
}
谁能告诉我带参数的信号究竟是如何工作的?我的意思是...如果我声明了信号 f.e.:
void sign1(int)
我应该如何指定我想用那个信号发送什么整数?另外,我可以用多个参数声明信号吗?喜欢:
void sign2(int, int)
再一次...我想用 sign2 发送我拥有的四个变量中的两个。这可能吗,应该怎么做?下面是一个更详细的例子来说明我的问题:
class Board
{
signals:
void clicked(int, int);
private:
int x1{4}; int x2{4}; int x3{5}; int x4{8};
}
并且有 board.ui 个带按钮的文件。单击按钮后,我想发送到插槽,例如 x1 和 x3。示例:
connect(ui->button, SIGNAL(clicked(int, int)), obj2, slot2);
我希望它能以某种方式清楚。非常感谢您的帮助。
QObject::connect()
像这样工作(在一般情况下,不使用 lambda):
connect(obj1, obj1_signal, obj2, ob2_slot)
由于 class QPushButton
中没有信号 clicked(int, int)
(我假设您正在使用),因此无法用于连接。
如果你想在一个按钮中有信号clicked(int, int)
,你可以subclass QPushButton
,添加信号,并使用emit
发送信号处理点击事件的地方。
但是,这不是一个好的设计,因为您必须在按钮 class 中存储一个 Board 对象(或至少是对它的引用),这与 class.
相反,您可以有一个插槽 Board::buttonClicked()
,连接到 QPushButton::clicked(bool)
。然后在那个插槽中,你可以做 emit Board::clicked(int, int)
.
signal/slot连接的规则可以表述如下:
You can ignore signal arguments, and you cannot create slot arguments from nothing
这是什么意思? 如果你的信号有一个参数,你的插槽最多也应该有一个参数。见下表。
在第一行,你有一个带有两个参数的信号,因此,你的插槽可以有两个参数(使用所有信号参数),或一个参数(忽略信号的一个参数)或无参数(忽略两个信号参数)
在第二行,您有一个带有一个参数的信号
valueChanged(int)
。您的插槽可能有一个参数或没有参数(忽略信号参数)但 可能不会 有两个 或更多参数you cannot create values
.在第三行,信号
textChanged(QString)
无法与setValue(int)
连接,因为我们无法从 QString 创建int
值。第四行遵循这些规则。如果信号没有参数,连接的信号不能创建新参数,因此
update()
是正确的,setValue(int)
不是。另一个需要注意的点是 signal/slot 的重载。在这种情况下,许多 signals/slots 具有相同的名称但具有不同的数字或不同类型的参数。 您可能有 class
QLCDNumber
,其中插槽display
有很多过载。在此 cas 中,您必须明确定义要按说明使用的信号槽对 here
您可以试试下面的例子:
示例:
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *window = new QWidget();
window->setAttribute(Qt::WA_DeleteOnClose);
QVBoxLayout *topLayout = new QVBoxLayout(window);
//Set up of GUI
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 100);
QSpinBox *spin = new QSpinBox;
spin->setReadOnly( true );
QHBoxLayout *horizontalLayout = new QHBoxLayout;
horizontalLayout->addWidget(slider);
horizontalLayout->addWidget(spin);
topLayout->addLayout(horizontalLayout);
// using pointer to member function
QObject::connect(slider, &QSlider::valueChanged,
spin, &QSpinBox::setValue);
// set the slider position and hence the QSpinBox value too
slider->setValue(40);
// Uncommenting the following connect will result in a compile time error.
// The signal passes no arguments whereas the slot is expecting a single
// argument.
// By using function pointers we get compile time parameter list checking.
// Using the old-style SIGNAL/SLOT macros this would have been detected
// as a run time warning only.
//QObject::connect(slider, &QSlider::sliderPressed,
// spin, &QSpinBox::setValue);
QTextEdit *textEdit = new QTextEdit();
textEdit->setAttribute(Qt::WA_DeleteOnClose);
// Uncommenting the following connect will result in a compile time error.
// The signal is passing an incompatible parameter to the slot.
// By using function pointers we get compile time parameter type conversion.
// Using the old-style SIGNAL/SLOT macros this would have been detected
// as a run time warning only.
//QObject::connect(slider, &QSlider::sliderMoved,
// textEdit, &QTextEdit::setFontFamily);
window->show();
return app.exec();
}