信号与槽
QPushbutton *b1=new QPushbutton(this)
QPushbutton *b2=new QPushbutton(this) 1
connect(b1,&QPushbutton::pressed,b2,&QPushbutton::close);
其作用即是按b1按钮时,对b2按钮实现close函数(也就是槽函数)b2关闭
语法 :
b1:信号发出者,指针类型
&QPushButton::pressed:处理的信号(signal), [&发送者类名::信号名字]
b2:信号接受者,指针类型
&QPushbutton::close:槽函数,信号处理函数 [&接受的类名::槽函数名字]
自定义槽函数
任意的成员函数,普通全局函数,静态函数
槽函数需要和信号一直(参数,返回值)
由于信号都是没有返回值的,所以槽函数一定没有返回值
connect(&b3,&QPushButton::released,this,&MainWidget::changeWin);
changeWin就是自定义槽函数
void MainWidget::changeWin()
{
this->hide();
w.show();
qDebug()<<“Yes,I Can Hear U!”;
}
自定义信号
信号必须由signals关键字申明
信号没有返回值但可以有参数
信号就是函数的声明,只需声明无需定义
使用 emit mySignal();发射信号
在常用控件QPushButtion里继承了QAbstractButton的信号
定义为按下按钮时发射信号(必须有发射的动作)
实例
在MainWidget类(QWidget派生而来)中定义一个副窗口(另一个从QWidget派生出的类作为成员变量),主窗口调用副窗口轻而易举,只需定义一个槽函数实现即可。而副窗口对主窗口通讯,则需要副窗口自己发射信号让主窗口引起“中断”
subWidget 副窗口类
#ifndef SUBWIDGET_H
#define SUBWIDGET_H
#include <QWidget>
#include<QPushButton>
class subWidget : public QWidget
{
Q_OBJECT
public:
explicit subWidget(QWidget *parent = nullptr);
void sendSlot();
signals:
MySignal();
private:
QPushButton b;
};
则在构造函数里设定好信号发射的条件:当空间b被按下时调用sendSlot()发射信号
这样在主窗口隐藏时,副窗口就可以通过发射信号给主窗口
#include "subwidget.h"
subWidget::subWidget(QWidget *parent) : QWidget(parent)
{
this->setWindowTitle("sub");
b.setParent(this);
b.setText("切换到主窗口");
connect(&b,&QPushButton::clicked,this,&subWidget::sendSlot);
resize(400,300);
}
void subWidget::sendSlot()
{
emit mySignal();//发送广播信号主窗口也能收到
emit mySignal(2333,"Can U Hear Me?");
}
#endif // SUBWIDGET_H
Lambda表达式
//Lambda表达式:匿名函数对象
//c++11增加到新特性,项目文件:CONFIG+=C++11
//Qt配合信号一起使用方便至极
//不必再定义多余的槽函数
connect(b4,&QPushButton::clicked,//clicked是有参信号按下参数为false默认也是false
//[]函数传参 //=把外部所有局部变量以及类中所有成员以值传递方式全传进来(默认为只读形式)想改值需要在()后加上mutable,比较安全
//this:类中的所有成员以值传递方式
//&:把外部所有局部变量,引用方式千万不要在引用时对函数操作动态分配内存的指针,因为指针还没有被释放引用它就导致冲突
//()传递信号参数
//{}函数体
[=](bool isCheck)mutable
{
qDebug()<<"奇怪的知识增加了!";
qDebug()<<isCheck;
}
);
补充
重载信号
Qt5中connect区分重载信号的方法是用指针指向各个重载信号,在连接时重载的信号用之前定义的指针表示
#ifndef SUBWIDGET_H
#define SUBWIDGET_H
#include <QWidget>
#include<QPushButton>
class subWidget : public QWidget
{
Q_OBJECT
public:
explicit subWidget(QWidget *parent = nullptr);
void sendSlot();
signals:
void mySignal();
void mySignal(int , QString);//带参数的信号
private:
QPushButton b;
};
#endif // SUBWIDGET_H
/*信号有重载,产生二义性解决方法:利用函数指针确定要调用哪个信号函数/槽函数
*所以就不能表示为:connect(&w,&subWidget::mySignal,this,&MainWidget::deal);
*信号函数指针定义方法: void (定义域::*指针名)(重载函数参数表)=&定义域::信号名
*/
void (subWidget::*FistSignal)()=&subWidget::mySignal;
void (subWidget::*SecondSignal)(int,QString)=&subWidget::mySignal;//如此就定义好两个重载信号的指针
connect(&w,FistSignal,this,&MainWidget::dealsub);//用的是第一的无参的
connect(&w,SecondSignal,this,&MainWidget::deal);//用的是第二个有参的
Qt4中connect区分重载信号是在直接用SIGNAL()会显示信号类型选择,关键字SLOT()显示定义的槽函数选择。connect(&b1,SIGNAL(MySignal()),&b2,SLOT(MySlot());
但是Qt4中SIGNAL后括号只要是字符串编译的时候就不会报错,运行时才会出错。故不太容易后期维护。