Qt图标

信号与槽(Signal & Slot)是Qt编程的基础,也是Qt的一大创新。因为有了信号与槽的编程机制,在Qt中处理界面各个组件的交互操作时变得更加直观和简单。

本文对信号与槽的内容进行了直观地介绍,让你一文读懂信号与槽。

一、什么是信号与槽

信号(Signal)就是在特定情况下被发射的事件,例如PushButton常见的信号就是鼠标单击时发射的clicked()信号,而一个ComboBox最常见的信号是选择的列表项变化时发射的CurrentIndexChanged()信号。GUI程序设计的主要内容就是对界面各组件的信号响应,只要知道什么情况发射哪些信号,然后合理去响应和处理这些信号就好了。

槽(Slot)就是对信号响应的函数。与一般的C++函数一样,槽就是一个函数,可以定义在类的任何部分(如public、private或protected),可以具有任意参数,也可以被直接调用。与一般函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数自动被执行。

信号与槽的关系

二、信号与槽如何关联

信号与槽的关联是用QObject::connect()函数实现的。connect()是QObject类的一个静态函数,而QObject是所有Qt类的基类。在实际调用时也可以忽略前面的限定符,直接调用connect。

(1)在Qt5之前的版本中connect的基本格式是:

QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

其中sender是发射信号的对象名称,signal()是信号名称。信号可以看作是特殊的函数,需要带括号,有参数时需要指明参数。receiver是接收信号的对象名称,slot()是槽函数的名称。比如以下代码:

QObject::connect(pushButton, SIGNAL(clicked()), widget, SLOT(close()));

实现了“点击按钮关闭窗口”的功能。

(2)从Qt5.0版本开始,connect函数引入了新的用法(原来的方法正常使用),改进了指定信号函数和槽函数的方式,不再使用SIGNAL()和SLOT()宏,而是采用“&函数所在类名::函数名”的格式。比如上面的例子,

QObject::connect(pushButton, &QPushButton::clicked, widget, &QWidget::close);

(3)默认地,Qt在每一个setupUi函数中包含了如下的关联函数,

QMetaObject::connectSlotsByName(QObject *object);

功能是递归搜索给定object对象的所有子对象,并将来自这些子对象的匹配信号关联到以下形式的槽函数:“on_子对象名称_信号名”。比如你自己定义了一个函数,

void on_pushButton_clicked();

那么这个函数将作为槽函数自动关联到pushButton的clicked()信号,而不再需要显式地调用connect函数。

灵活的关联方式

三、需要知道的一些规则

(1)一个信号可以关联多个槽,槽函数按照建立连接时的顺序依次执行。

(2)多个信号可以连接同一个槽,任意一个信号被发射时都会触发槽函数。

(3)一个函数被发射时,与其关联的槽函数通常被立即执行。只有当信号关联的所有槽函数都执行完毕后,才会执行发射信号处后面的代码。

(4)一个信号可以连接另外一个信号,只需将SLOT(slot())替换为被连接的信号SINGAL(signal2())。这样,当一个信号被发射时,也会发射另外一个信号,实现某些特殊的功能。

(5)严格来讲,信号与槽的参数个数与类型要一致,至少信号参数不能少于槽的参数,否则会出错。

(6)使用信号与槽的类,必须在类的定义中加入宏Q_OBJECT。

(7)信号函数只需要声明,不需要定义(实现),而槽函数需要定义(实现)。

(8)为了提高开发效率,Qt 的各个控件类都提供了一些常用的信号函数和槽函数。

(9)实际开发中,可以使用 Qt 提供的信号函数和槽函数,也可以根据需要自定义信号函数和槽函数。

看了本文,你对Qt的信号与槽了解了吗?欢迎大家多多关注评论转发!

举报/反馈

未来奇兵

79获赞 85粉丝
物理学博士;编程爱好者;户外自驾游
关注
0
0
收藏
分享