GUI编程中通常使用回调函数进行事件处理,而回调函数通常是一个函数指针,不同的事件,不同的对象都有着各自的回调函数,当事件到来时,系统会通过调用对应的回调函数来完成相应的处理.
QT引入了信号和槽机制来取代回调函数,凡是继承QObject的类都可以具有信号和槽成员,并可以使用它们,信号和槽的使用可以有效减少函数指针的使用,对于事件响应管理更加容易,信号和槽没有严格规定函数的类型,因此在调用过程中是安全的.
信号和槽的使用可以实现信息封装,增加程序的灵活性,信号和槽都采用函数作为存在形式,在qt程序初始化或者运行的过程中,可以静态或动态的将信号与槽相关联,当某一事件来时,会发射信号,但是发射后,她并不需要关心信号的处理者是谁,当触发槽函数时,说明与其关联的信号会被接收,但它不需要了解谁发出了信号,它只需要负责进行相应的处理即可.
1.信号
信号是QT中对事件是一中抽象,当一个事件到来时,会发射信号,所谓的发射信号,就是通过Qt中特有的通信机制,调用和信号相关的各个槽函数,因此当发射信号时,将执行与其相关联的槽函数,信号采用函数的形式,当所有与信号关联的函数全部返回后,信号函数才会返回,信号函数在形式上与标准c++中的虚函数类似,信号函数只有头文件中函数的声明,而没有函数的定义(函数体).信号的声明形式如下:
signal:
void MySignal();
void MySignal(int x);
void MySignalParam(int x,int y);
注意:信号的返回值必须为void型,因为事件是一件中断,对于突发的中断,不可能期望有返回值.
2.槽
槽是QT中负责信号处理的实体,当信号发射时,与信号关联的所有槽会依次执行,槽也采用函数的形式,也需要声明,不过槽需要有实际的函数定义,相当于在c++中对虚函数的多态实现,槽函数声明如下:
public slot:
void MySignal();
void MySignal(int x);
void MySignalParam(int x,int y);
注意:槽函数具有访问权限的标识,和c++类的成员函数的标识相同,分别为:
public:说明该槽函数可以被其他类的信号关联.
protected:只能被类本身和其子类的信号所关联.
priviate:只能被类本身的信号所关联.
在QT的基类QObject中有一个成员函数QObject::connect()用来完成信号和槽的映射,函数原型如下:
#include <QObject>
static bool QObject::connect(const QObject * sender, const char * signal, const QObject * receiver,const char * menber);
QT要求必须使用宏SIGNAL将信号函数转化为指针指定的类型.使用宏SLOT 转化函数指针.
SIGNAL(funname(param_type_1,param_type_2,...))
SLOT(funname(param_type_1,param_type_2,...))
funname函数名 param_type_x是函数中对应参数的类型.
3.建立信号和槽的映射
方法一:
1)在mainwindow.h的类MainWindow的定义中声明槽函数,代码如下:
public slots:
void on_pushButton_clicked();
2)定义槽函数体在mainwindow.cpp文件中,代码如下:
void MainWindow::on_pushButton_clicked()
{
ui ->label->setText(''hello world'');
}
3)建立映射,在类MainWindow的构造函数中添加如下语句,以便将信号和槽函数进行连接:
QObject::connect(ui->pushbutton,SIGNAL( clicked() ),this,SLOT( on_pushBuuton_clicked() );
方法二:
在.ui文件中,右击按钮,选择''go to slot''选项,选择信号"clicked",单机确定按钮.
系统自动生成槽函数声明和定义,并建立内部映射.
只需在槽函数体内编写槽函数体内编写槽函数的功能即可,添加语句如方法一中的步骤2.
方法三:
在.ui界面,选择"改变信号/槽"选项,单击"+"添加新的槽函数,确定完成槽函数的添加,最后重复方法一中的步骤1和步骤2完成槽函数声明和定义.