初学Qt:信号与槽

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dashumak/article/details/78220423
 

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

猜你喜欢

转载自blog.csdn.net/dashumak/article/details/78220423