Qt中的信号和槽

一.信号和槽

1.const用法

2.信号和槽概念

信号和槽基于元对象系统实现的

2.1 本质

函数调用,在信号和槽中转换成字符串的逻辑结构

2.2 构建信号和槽的常用函数

connect()

QObject::connect(&a, SIGNAL(a_sigal()), &b, SLOT(b_slot()))本质是建立信号和槽的关联关系

connext执行绑定规则而不是执行函数

信号

a_signal()(信号):本质是一个 "事件触发器",本身没有函数体(理解成空函数)

只有通过 emit a.a_signal(); 触发时,才会 "通知 Qt 有信号发射了"

b_slot()(槽):只有当 a 发射了 a_signal() 信号后,Qt 才会根据 connect 绑定的规则,主动调用 b 的 b_slot() 函数,这时候 b_slot() 才会执行。

所以在代码的类中不用补充a_sigal()(但是必须在类中声明 a_sigal() 信号)

.h代码

3. 两种构建信号和槽的方法

3.1函数分析

connect函数方法:

connect中引用两个类名的地址,同时利用SIGNAL(a_signal())和SLOT(...)来声明

函数指针形参:

同样是connect函数,但是将SIGNAL和SLOT换成类引用形式,比如&A::a_signal

3.2防止重载

connect函数方法解决

添加对应的参数类型

指针形参需要引用qOverload<...>(...)函数来保证良好的解决重载问题

4. 信号和槽的参数和重复性

信号有几个参数参,槽函数就有几个参数

4.1问题

接下来探讨信号和槽的参数一定对应吗

(1)信号有参数;槽函数无参数(或者槽参数少于信号参数)

槽函数是最终要执行的,即便传递的参数多于槽参数,在槽函数中也用不上,所以传递后也不影响

(2)信号不传递参数,槽需要参数(或者槽参数多余信号传递的参数)

这样是不允许的,信号传递的参数少于槽函数参数时,槽函数中无法识别剩下没有传递的参数,所以无法编译

综上:

参函数的参数<=信号函数的参数

5. 信号和槽重复关联

5.1 举例

同一个信号执行多次,但是每次对应的槽函数不同,此时槽函数是进行覆盖操作还是多次执行又或如何

5.2 结论

同一信号 → 多个不同槽函数(依次连接) 不覆盖 按连接顺序依次执行所有槽

同一信号 → 同一个槽函数(重复连接) 可能多次执行 / 覆盖 取决于 Qt::ConnectionType 连接类型

重复连接同一槽(默认类型):槽会执行多次

5.3 如何避免重复执行

用 Qt::UniqueConnection 连接类型,重复连接会失败(返回 false),确保同一信号 - 槽只连一次

例如:

bool conn1 = QObject::connect(&a, qOverload<>(&A::a_signal), &b, qOverload<>(&B::b_slot), Qt::UniqueConnection);

bool conn2 = QObject::connect(&a, qOverload<>(&A::a_signal), &b, qOverload<>(&B::b_slot), Qt::UniqueConnection);

重复连接时,Qt 不会报错,只是返回 false 告知连接失败,程序仍能正常运行

信号和槽不要多次绑定,避免执行多次槽函数

要执行多次绑定,都放在一个接口上(主类),这时对控件进行信号和槽的绑定时方便

5.4代码

6.多个槽信号的合并

6.1 两类函数的混合双打

(1). sender():返回的是任意类型的

如果在由信号触发的槽函数中调用此函数,将返回发送该信号的对象的指针;否则返回空指针(nullptr)。该指针仅在从该对象的线程上下文中调用此函数的槽函数执行期间有效

(2). qobject_cast(const QObject *object)

如果给定对象的类型为 T(或 T 的子类),则将该对象转换为 T 类型并返回;否则返回空指针(nullptr)。若传入的对象本身是空指针,该函数也会返回空指针

6.2合并的意义

QObject::sender () ------ 槽函数里 "找信号是谁发出来的"

比如三个按钮,点击那个按钮(调用哪个按钮函数),给sender()返回哪种地址,就能找到是谁发的信号,所以不用多个槽函数

解决什么问题?

当多个相同类型的控件绑定同一个槽函数时,不用写多个槽函数,只需在槽里用 sender() 区分是谁触发的即可

qobject_cast<T>() ------ Qt 专属的 "安全类型转换"

把 QObject* 类型的指针安全转换成指定的 Qt 子类类型(比如 QPushButton*、QLineEdit*),转换失败返回 nullptr,不会像 C++ 原生 static_cast 那样崩溃

sender() 返回的是 QObject* 通用指针,无法调用子类(如 QPushButton)的专属方法(比如 text()),必须用 qobject_cast 转成具体类型才能用

类型转换

A *obj = qobject_cast<A *>(sender());

代码

思路回顾

信号和槽构建的函数 connect

信号和槽的重载问题解决方案

信号和槽的参数问题

信号和槽的重复关联

信号和槽的合并问题,合并的意义,用到哪两个函数

相关推荐
用户8055336980311 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner11 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz5 天前
QML Hello World 入门示例
qt
xcyxiner8 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner9 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner9 天前
DicomViewer (添加模型类)3
qt
xcyxiner10 天前
DicomViewer (目录调整) 2
qt
xcyxiner10 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能12 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G12 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt