Qt之信号与槽总结

Qt 信号槽是 Qt 整个架构的基础之一,因此它同 Qt 提供的组件、线程、反射机制、脚本、元对象机制以及可视化 IDE 等等紧密地集成在一起。Qt 的信号是对象的成员函数,所以,只有拥有信号的对象才能发出信号。Qt 的组件和连接可以由非代码形式的资源文件给出,并且能够在运行时动态建立这种连接。Qt 的信号槽实现建立在 Qt 元对象机制之上。Qt 元对象机制由 Qt 提供的 moc 工具实现。moc 也就是元对象编译器,它能够将用户指定的具有 Q_OBJECT 宏的类进行一定程度的预处理,给这个增加元对象能力。

信号和槽机制是QT的核心机制,是一种高级接口,应用于QT对象之间的通信,是QT的核心特性,也是QT区别于其它工具包的重要地方。信号和槽是QT自行定义的一种通信机制,独立于标准的C/C++语言,要正确的处理信号和槽,必须借助一个称为moc(Meta Object Compiler)的QT工具,MOC工具是一个C++预处理程序,为高层次的事件处理自动生成所需要的附加代码。

    在QT中信号和槽取代了传统GUI框架中的回调函数,信号和槽能携带任意数量和任意类型的参数,是类型完全安全的。所有从QObject或其子类(如Qwidget)派生的类都能够包含信号和槽。当对象改变其状态时,信号就由对象发射(emit)出去,但对象不知道另一端是谁在接收信号。槽用于接收信号,但槽是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接,而且对象并不了解具体的通信机制。

 

什么是信号槽?

这个问题我们可以从两个角度来回答,一个简短一些,另外一个则长些。

让我们先用最简洁的语言来回答这个问题——什么是信号槽?

信号槽是观察者模式的一种实现,或者说是一种升华;
一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知;
一个槽就是一个观察者,通常就是在被观察的对象发生改变的时候——也可以说是信号发出的时候——被调用的函数;
你可以将信号和槽连接起来,形成一种观察者-被观察者的关系;
当事件或者状态发生改变的时候,信号就会被发出;同时,信号发出者有义务调用所有注册的对这个事件(信号)感兴趣的函数(槽)。
信号和槽是多对多的关系。一个信号可以连接多个槽,而一个槽也可以监听多个信号。
信号和槽的机制实际上是观察者模式的一种变形。它是面向组件编程的一种很强大的工具。现在,信号槽机制已经成为计算机科学的一种术语,也有很多种不同的实现。

类定义时, 使用的moc相关的宏 

Q_OBJECT
#define signals public. Qt4中为 protected. Qt5为支持connect函数指针写法, 定义为 public.
#define slots
连接信号槽使用的宏 (Qt4 的写法, 在函数名前添加数字, 用于标识[2]信号, [1]槽函数, [0]普通方法) 
#define SLOT(a) "1"#a
#define SIGNAL(a) "2"#a
发信号: #define emit


Qt 每个继承了 QObject, 并使用了 Q_OBJECT 的类在执行 moc 时, 会生成 moc_xxx.cpp 文件. 在该文件中有该类的内省表. 内省表记录了索引值 与各函数-信号-槽函数之间的对应关系. 在 Qt 中都是使用索引值来作为参数传递函数的.
每个类中的每个信号, 都维护了一个 ConnectionList, 用于存储连接到其上的目标函数.
在 connect 时, 需要提供 sender, signal func, receiver, call func. (当然还有连接方式, 不过和此处要讲的流程关系不大). connect 函数将 receiver 和 call func 打包成一个 Connection 节点, 并存储在 sender 的 singnal func 对应的 ConnectionList 中.
在 emit signal 时, 调用了QMetaObject::activate(), 该方法会根据传入的 sender 和 singnal func 对应的索引, 找到 ConnectionList. 并回调这些方法.

上一篇:JavaScript 模拟装饰者模式


下一篇:c – 信号和插槽是语法糖还是它们还有更多?