pS:提供一个学习C++函数的方法:一个函数主要有4个要素:函数功能、输入参数、返回值、以及函数 所在的头文件,清楚即可。
核心函数是connect函数,将信号singal函数和槽slot函数联系起来
1、首先给出QT5中connect函数的格式:
1 connect(&b1,&QPushBotton::pressed,this,&MainWidget::close);
2 /* &b1:信号发出者,指针类型。
3 &QPushBotton::pressed 要处理的信号,&发送者的类名::信号名字
4 this:信号接受者,指针类型
5 &MainWidget::close 槽函数,即接受到信号之后的响应函数,&接收者类名::槽函数名字
其中信号和槽(slot)都是函数,既可以是QT库中已声明好的函数,也可以是自定义的函数。
注:
槽函数需要和信号一直(参数、返回值)
由于信号都是没有返回值的,所以槽函数一定没有返回值
2、之后给出QT4中connect函数的格式:
1 QObject::connect(&b1,SIGNAL(clicked()),this,SLOT(hide()));
2 /*第1、3个参数与之前提到的相同
3 SIGNAL(clicked()) 这个参数是字符串型,SIGNAL()将信号函数转化成字符串型
4 SLOT(clicked()) 这个参数是字符串型,SLOT()将槽函数转化成字符串型*/
注:
- 不能将全局函数或lambda表达式(匿名函数)写入connect函数中。
- 使用字符串导致QT4存在一个缺点:QT4是不会检查字符是否匹配,同样不会在这里进行编译报错。
此外还要注意,每一个支持信号与槽机制的类必须派生于QObject(或者是QObject的若干次继承之后,如QWidget),且在类的声明中必须包含Q_OBJECT宏。
3、QT4中自定义槽函数和信号函数
自定义槽函数要与相应的信号函数保持一致,包括输入参数以及返回值。
(1)自定义槽函数首先要在头文件中声明,有public slots、private slots、protected slots三种。
//头文件当中
...
public slots:
void ChangeWindow();
...
其次要在.cpp文件中定义。
void SubDialog::ChangeWindow()
{
this->close();
}
相应的在程序当中connect调用格式如下:
QObject::connect(&PB_ComeBack,SIGNAL(clicked()),this,SLOT(ChangeWindow()));
(2)自定义信号函数要在头文件中signals中声明,可以是带参数的函数。如下:
//头文件当中
...
signals:
void mySignal();
...
在.cpp文件中无需定义,直接用即可,使用时需要在前边加上emit。如下:
//相应的.cpp文件
...
void SubDialog::ChangeWindow()//主窗口显示
{
emit mySignal();//在一个函数当中调用(发射)信号函数。
this->close();
}
...
4、信号可以链接信号
调用格式:
QObject::connect(&b1,SIGNAL(clicked()),&b2,SIGNAL(pressed()));
表示:
b1发送clicked()信号,然后b2也发送pressed()信号。但是发过来b2发送pressed()信号,b1并不发送clicked()信号。
5、连接可以被移除
调用格式:
disconnect(&b1,SIGNAL(clicked()),&b2,SLOT(pressed()));
这种情况很少用,因为删除对象时,Qt会自动移除与这个对象相关的所用连接。
6、信号的重载问题
C++比C独特的一点在与提供了函数重载,QT中的信号函数也同样会出现重载现象,但是在处理重载时QT4和QT5是不同的。
QT4中connect函数使用的格式如下:
1 QObject::connect(&b1,SIGNAL(clicked()),this,SLOT(hide()));
//第二个参数是信号函数,若出现函数重载,可以直接在clicked(),括号中加入相应的参数,同样槽函数也要保持一致,加入输入参数。
//即QT4利用宏SIGNAL和SLOT将函数的参数显式的显示出来
但是QT5 connect函数使用的格式如下:
1 connect(&b1,&QPushBotton::pressed,this,&MainWidget::close);
//这种格式信号参数和槽函数的参数没有显式的提供,即没有“()”。因此不能直接加入参数,实现重载。QT5的解决方式是引入了函数指针。
//基于QObject::connect(*sender,&signal,*receiver,&slot)格式的语句,如下:
//...
//信号与槽重载问题
//带参数
void (QComboBox::*funSignal)(int) = &QComboBox::currentIndexChanged;//这个格式即是函数指针的格式 QObject::connect(comboBox,funSignal,*receiver,&slot);//当然二者的槽函数也应该不同
&slot);//当然二者的槽函数也应该不同
//不带参数
void (QComboBox::*textSignal)() = &QComboBox::currentIndexChanged; QObject::connect(comboBox,textSignal,*receiver,&slot);
&slot);
//...
同样槽函数重载也是这样解决
另外QT5是兼容QT4的,因此QT5也可以使用SIGNAL和SLOT两个宏关键字。
最后提示一点,一个信号可以对应多个槽函数,但是这些槽函数的响应顺序是随机的。因此一旦出现涉及到动作的先后顺序问题,最好自定义一个槽函数,然后按动作顺序加入相应的相应函数。
关于QT4信号与槽的详细介绍,推荐一篇博文:http://blog.csdn.net/qter_wd007/article/details/5598264