QT采用了一种全新的对象和方法的关联与通信机制,称为信号和槽机制。信号和槽机制独立于c++编译器,在编译之前需要经过QT的专门预处理工具MOC(meta object compiler,元组件编译器)对代码进行预处理后才能进一步进行c++代码的编译。MOC会将qt应用程序中特有的代码自动转换为相应的c++语法代码。
QT用信号和槽机制来取代GUI编程中通常使用的回调函数进行事件处理的机制(如MFC用的是事件和回调函数机制)。
信号和槽都采用函数作为存在形式。在Qt程序初始化或运行的过程中,可以静态或动态的将信号和槽相关联。当某一事件到来时,会发射信号,但是发射后,它并不需要关心信号的处理者是谁。当触发槽函数时,说明与其关联的信号被接受,但它不需要了解谁发出了信号,它只需要负责进行相应的处理即可。
1.信号
信号是qt中对事件的一种抽象,当一个事件到来时,会发射信号。所谓发射信号,就是通过Qt的通信机制,调用和信号相关的各个槽函数。信号采用函数的形式,当所有与信号关联的函数全部返回后,信号函数才会返回。信号函数在形式上与标准c++中的虚函数类似,信号函数只有在头文件中函数的声明,而没有函数的定义。
信号的声明形式如下:
signal:
void Mysignal();
void Mysignal(int x);
void MySignalParam(int x, int y);
2.槽
槽是Qt中负责信号处理的实体,当有信号发射时,与信号关联的所有槽会依次执行。槽也采用函数的形式,不过槽需要有实际的函数定义,相当于在标准c++中对虚函数的多态实现。
槽函数的声明如下:
void Myslot();
void Myslot(int x );
void Myslotparam(int x, int y);
槽函数的定义同普通的c++函数无异,支持c++函数的一些特性。槽函数可以采用标准c++函数的使用方式,在代码中直接调用。槽函数具有访问权限的标识,分别为:public,protected,private。public说明该槽函数可以被其他类的信号所关联,protected说明只能被类本身和其子类的信号所关联,private说明该槽函数只能被本类本身的信号所关联。
在Qt的基类QObject中有一个成员函数用来完成信号和槽的映射,函数原型如下:
#include <QObject>
static bool QObject::connect(const QObject *sender, const char *signal, const QObject * receiver, const char *member);
sender和receiver分别指定了被关联的信号和槽的发送者和接受者。signal是信号,Qt要求必须使用宏SIGNAL将信号函数指针转化为指定的类型。member是槽,Qr要求必须用宏SLOT转化函数指针。宏的参数形式如下:
SIGNAL(funname(param_type_1, param_type_2,....))
SLOT(funname(param_type_1, param_type_2,...))
其中,funname是函数名, param_type_x是函数中对应参数的类型。