Qt 中的信号与槽机制对于界面开发来说是非常方便的,界面上会有各种各样的部件,而这些部件之间常常需要通信,比如点击一个按钮,会触发一个效果,点击按钮就是一个信号,触发的效果就是一个槽函数。信号与槽还可以用来进行线程之间的通信,并且是线程安全的。
简要说一下信号与槽的底层原理。
信号与槽的实现是借助了Qt 的元对象系统,元对象系统有一个元对象编译器,程序编译之前会有一个预处理过程,预处理将一个类/对象中的信号,槽的字符串值分别保存在一个容器中,可能是字符串或者其他的有序容器。
现在有两个容器,比如string_sig,保存了所有的信号的字符串值;string_slot保存了所有的槽函数的字符窜值。
每次调用connect()函数建立信号与槽的连接,就是将给定信号与给定的接收方及其槽函数存储在发送方对象的映射容器中,比如multimap,建立起信号与槽的一一对应关系。
发射信号其实就是调用信号函数(信号就是一种函数),根据该信号的索引在multimap中找到对应的槽函数,在调用槽函数即可。
信号与槽的本质就是函数的调用。
下面是一个用C++ STL实现简单信号与槽的例子。
#include"object.h"头文件
#ifndef DB_OBJECT
#define DB_OBJECT
#include <map>
# define db_slots
# define db_signals protected
# define db_emit
class Object;
struct MetaObject//元对象
{
const char* sig_names;
const char* slts_names;
static void active(Object* sender, int idx);
};
struct Connection//保存接收方及其序号
{
Object* receiver;
int method;
};
typedef std::multimap<int, Connection> ConnectionMap;
typedef std::multimap<int, Connection>::iterator ConnectionMapIt;
class Object
{
static MetaObject meta;
void metacall(int idx);
public:
Object();
virtual ~Object()