信号槽是qt框架引以为豪的机制之一,熟练使用和理解信号槽,能够设计出解耦的非常漂亮的程序,有利于增强我们的技术设计能力。
qt采取了一种全新的对象和方法的关联与通信机制,称为信号和槽函数。qt用信号和槽机制来取代gui编程中通常使用的回调函数进行事件处理的机制,如mfc采用的是事件和回调函数机制。
在qt程序初始化或运行的过程中,可以静态或动态的将信号和槽函数相关联。当某一事件到来时,会发射出一个信号,但是发射完成后,它并关心谁来处理这个信号。
当触发槽函数时,说明与其关联的信号被接受,但是它并不需要了解谁发出了信号,它只需要负责进行相应的处理。
1.信号是qt中对事件的一种抽象,当一个事件到来就会发射信号,发射信号是通过qt的通信机制,调用和信号相关的各个槽函数,信号采用函数的形式,当所有与信号关联的函数全部返回后,信号函数才会返回。
信号声明的形式如下:
signal:
void Mysignal();
void Mysignal(int x);
void MySignalParam(int x,int y);
2.槽是qt负责信号处理的实体,当有信号发射时,与信号关联的所有槽会依次的执行,槽也会采用函数的形式,不过槽需要有实际的函数定义,相当于在标准c++中对虚函数的多态实现。
槽函数的声明如下:
void Myslot();
void Myslot(int x);
void MuslotParam(int x,int y);
槽函数的定义和普通的c++函数一样使用,槽函数具有访问权限的标识:分别为public,private,protected
l public(共开)说明该槽函数可以被其他类的信号所关联
l protected(保护)说明只能被本身和其他子类的信号所关联
l private(私有)说明该槽函数只能被本类本身的信号所关联
qt的基类QObject类中有一个成员函数来完成信号和槽的映射,函数原型如下:
#include <QObject>
static boolQOject::connect(const QObject *sender,const char *signal,const QObject*receiver,const char *member);
sender:代表被关联的信号的发送者
receive:代表槽的接受者
signal:是信号,qt中要求必须使用宏SIGNAL将信号函数指针转化为指定的类型。
member是槽,Qt必须要求用宏SLOT转化函数指针。
宏的参数如下:
SIGNAL(funname(param_type,param_type_2,...))
SLOT(funname(param_type_1,param_type2,...))
注:funname是函数名,param_type_x是函数中对应参数的类型
l 所谓信号槽,实际就是观察者模式,当某个事件发生之后,比如:按钮点击了一下,就会发出一个信号,这种发出就类似于广播,如果有对象这个信号感兴趣,它就会使用连接connect函数,意思就是用自己的一个函数来处理这个信号,这个函数就是称之为槽(slot)。也就是说,信号发出之时,被连接的槽函数会自动的被回调。这就类似于观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
上面写的connect()函数就是我们最常用的形式:
connect(sender,signal,receiver,slot);
connect()一般会使用前面四个参数,第一个是发出信号的对象。第二个就是发送对象发出的信号(是单击还是双击),第三个是接受信号的对象(窗体接收到这个信号),第四个接受对象在接受到信号之后所需要调用的函数,当sender发出信号signal之后,会自动调用receive的slot函数。
信号槽机制:
1. 一个信号可以连接多个槽,当信号发出时,槽函数都会被调用,但是调用的顺序是随机分配的,不确定的。
2. 多个信号可以连接到一个槽,任何一个信号都让槽函数执行。
3. 一个信号可以和另外一个信号相连,第一个信号发出时,第二个信号也同时发出,除此之外,信号和信号连接上与信号和槽连接方式相同。
4. 连接disconnect函数删除,一个对象删除后,qt会自动删除这个对象的所有连接。
5. 信号和槽函数必须有相同的参数类型,这样信号和槽函数才能成功连接。