信号槽¶
发出信号 - 执行信号连接的槽函数,就这么简单
注意:
-
一个信号发出后,会立即执行其连接的槽函数,等待槽函数执行完毕后,才会执行后面的代码
-
如果一个信号链接了多个槽,那么会等所有的槽函数执行完毕后才执行后面的代码,槽函数的执行顺序与连接顺序相同
信号¶
声明信号用 signals
,发送信号用 emit
注意:
-
所有的信号声明都是 公共 的,所以 Qt 规定不能在
signals
前面加public
、private
、protected
-
所有的信号都 没有返回值,所以返回值都用
void
-
所有的信号都不需要定义,在类中 声明即可
-
必须直接或间接继承自
QOBject
类,并且开头私有声明包含Q_OBJECT
-
信号参数的个数不得少于槽参数的个数
槽¶
声明槽用 public/protected/private slots:
不过如果使用下文提到的 QT5 的 connect()
函数来连接,那么任何函数(Lambda 表达式都可以)都可以作为槽函数,也就不需要用上面的声明了
连接¶
用 connect()
函数连接信号与槽,该函数有以下两种原型:
-
QT4 、QT5 都能用
static QMetaObject::Connection connect( const QObject *sender, // 信号发送对象指针 const char *signal, // 信号函数字符串,使用SIGNAL() const QObject *receiver, // 槽函数对象指针 const char *member, // 槽函数字符串,使用SLOT() Qt::ConnectionType = Qt::AutoConnection// 连接类型,一般默认即可 ); // 按下按钮,触发 close() 槽函数 connect(pushButton, SIGNAL(clicked()), dialog, SLOT(close()));
-
仅用于 QT5
static QMetaObject::Connection connect( const QObject *sender, //信号发送对象指针 const QMetaMethod &signal,//信号函数地址 const QObject *receiver, //槽函数对象指针 const QMetaMethod &method,//槽函数地址 Qt::ConnectionType type = Qt::AutoConnection//连接类型,一般默认即可 ); // 同上 connect(pushButton, &QPushButton::clicked, dialog, &QDialog::close);
其他¶
QSignalMapper¶
QSignalMapper
的核心在于 连接-配对-再发送
一个简单的例子:
Example
10 个按钮分别表示 0~9,要求按哪个按钮,QLineEdit
控件中同步显示按钮上对应的数字
连接:所有按钮的 clicked()
信号都连接到 signalMapper
上
配对:按钮与按钮上对应数字匹配
再发送:发送参数为按钮上对应数字的信号
SignalMapperWidget::SignalMapperWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::SignalMapperWidget{
ui->setupUi(this);
// 创建垂直布局,将垂直布局作为主布局
QVBoxLayout* vLayout = new QVBoxLayout(this);
// 创建编辑框,用于显示点击按钮的文字,并且文字在右边显示
QLineEdit* edit = new QLineEdit;
edit->setAlignment(Qt::AlignRight);
vLayout->addWidget(edit); // 将编辑框加入到垂直布局中
// 创建信号匹配器
QSignalMapper* signalMapper = new QSignalMapper(this);
// 创建0-9数字键,并都加入到网格布局中
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < 10; ++i){
QString txt = QString::number(i);
QPushButton *button = new QPushButton(txt);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, txt); // 将按钮和要发送的字符串配对
gridLayout->addWidget(button, i / 3, i % 3); // 一行显示3列
}
// 连接配对信号和设置文字槽
connect(signalMapper, SIGNAL(mapped(QString)),edit, SLOT(setText(QString)));
vLayout->addLayout(gridLayout);
resize(200, 200);
}
获取信号发送者¶
QObject* sender(); // 获取指向信号发送者的指针
解绑定信号槽¶
把连接函数中的 connect
改成 disconnect
即可