alin的学习之路(QT篇:一)(按钮,信号槽,lambda表达式)
1.QT简介
-
Qt:1991年由奇趣科技开发
-
Qt的优点:
- 跨平台
- 一定程度上简化了内存回收(一些delete可不用添加)
-
成功案例:
- Linux桌面环境KDE
- WPS
- 网络电话
- 谷歌地图
- VLC多媒体播放器
- 虚拟机软件
2.QPushButton基本使用
-
基本使用
//创建按钮 QPushButton *btn = new QPushButton; //显示按钮 //btn->show(); //想要将按钮显示在父界面上,要添加父依赖 btn->setParent(this); //设置文本 btn->setText("你好"); //设置窗口大小 this->resize(600,400); //设置大小锁定 this->setFixedSize(600,400); //创建第二个按钮 -- 构造函数有5个版本,其中一个(文本,父窗口) QPushButton *btn2 = new QPushButton("你好!",this); //移动按钮2的位置 btn2->move(100,0); //设置窗口标题 this->setWindowTitle("第一个Qt窗口");
-
自定义按钮
- 创建C++源文件,父类选择QWidget
- 修改父类为QPushButton
MyPushButton *mybtn = new MyPushButton; mybtn->setParent(this); mybtn->setText("自定义按钮"); mybtn->move(0,100);
3.对象树
- 当创建的对象父窗口是QObject ,或者是QObject派生下来的类,此对象会放到对象树上,当程序执行完毕,树上的内容会从下往上依次释放
- 先执行父类的析构函数,有子类,则执行子类的析构函数;若没有子类,则释放
Widget::~Widget()
{
qDebug() << "Widget的析构函数调用" ;
}
MyPushButton::~MyPushButton()
{
qDebug() << "MyPushButton的析构函数调用" ;
}
结果:
Widget的析构函数调用
MyPushButton的析构函数调用
4.信号和槽
-
connect函数
- 参数1:信号的发送者
- 参数2:发送的信号
- 参数3:信号的接收者
- 参数4:处理的槽函数
//信号槽 //信号槽在帮助文档中,信号要查看singal,槽函数要查看public slot,如果子类没有写要查看它的父类 //参数: 1.信号的发送者(指针) 2.发送的信号(地址) 3.信号的接收者(指针) 4.处理的槽函数(地址) connect(mybtn,&MyPushButton::clicked,this,&Widget::close);
-
信号槽优点:松散耦合 :将松散的内容通过信号槽连接起来
-
自定义信号和槽
- 信号
- 写在signals下
- 返回值为void
- 只需要声明,不需要实现
- 可以有参数,可以发生重载
- 槽函数
- 写在public slots下,高版本可以写在public下、全局函数下或者lambda
- 返回值void
- 需要声明,需要实现
- 可以有参数,可以发生重载
信号和槽的定义; class Teacher : public QObject { Q_OBJECT public: explicit Teacher(QObject *parent = nullptr); //信号函数要写在signals下 //1.返回值为void //2.只需要声明,不需要实现 //3.可以有参数,可以发生重载 signals: void hungry(); void hungry(QString foodName); public slots: }; class Student : public QObject { Q_OBJECT public: explicit Student(QObject *parent = nullptr); signals: //槽函数要写在public slots下,高版本一些其他的地方也可以 //1.返回值是void //2.需要声明,需要实现 //3.可以有参数,可以发生重载 public slots: void treat(); void treat(QString foodName); }; void Student::treat() { qDebug() << "请老师吃饭" ; } void Student::treat(QString foodName) { //使用qDebug()输出QString内容时,会带上一个"",输出char*后无"" //QString转char* //1.toutf8()转为QByteArray //2.data()转为char* qDebug() << "请老师吃饭,吃" << foodName.toUtf8().data() ; } void Widget::classIsOver() { emit this->zt->hungry(); emit this->zt->hungry("宫保鸡丁"); } 信号和槽的使用; //创建两个对象,并挂到对象树上,不需要delete this->zt = new Teacher(this); this->st = new Student(this); connect(this->zt,&Teacher::hungry,this->st,&Student::treat); classIsOver(); //使用该函数发送老师饿了的信号,emit关键字用于发送信号 //信号和槽发生重载后,需要利用函数指针指向函数地址 void(Teacher:: *ztSignal)(QString) = &Teacher::hungry; void(Student:: *stSlot)(QString) = &Student::treat; connect(this->zt,ztSignal,this->st,stSlot); //添加按钮,按按钮触发信号 老师饿了 QPushButton *btn = new QPushButton(this); btn->setText("下课"); //自定义信号:无参 void(Teacher:: * teacherSignal2)() = &Teacher::hungry; void(Student:: * studentSlot2)() = &Student::treat; connect(this->zt, teacherSignal2 ,this->st,studentSlot2);
- 信号
-
信号和槽的扩展
- 信号连接信号
- 一个信号可以连接多个槽函数
- 多个信号可以连接同一个槽函数
- 信号和槽的参数类型 必须一一对应
- 信号的参数个数可以多于槽函数,反之不可以,相同个数的参数类型也要一一对应
- 可以利用 disconnect 断开信号槽的连接
//信号触发信号 只能触发无参的 connect(btn,&QPushButton::clicked,this->zt,teacherSignal2);
-
Qt4版本的信号和槽的写法
- 优点:参数直观,写法简单
- 缺点:编译器不检测参数类型(参数类型不对应时可以运行起来,但是信号和槽触发时报错)
connect(this->zt,SIGNAL(hungry(QString)),this->st,SLOT(treat(QString)));
5.lambda表达式
-
基本语法:
[](){};
(大括号和分号之间加一对小括号表示调用该匿名函数) -
[]中的写法:
- =:代表值传递
- &:代表引用传递
- a:代表仅此变量,值传递
QPushButton *btn2 = new QPushButton("aaa",this); btn2->move(100,0); [=](){ btn2->setText("aaa"); }();
-
加上mutable修饰符后,可以修改按值传递进来的拷贝
QPushButton * myBtn = new QPushButton (this); QPushButton * myBtn2 = new QPushButton (this); myBtn->move(0,100); myBtn->setText("myBtn"); myBtn2->setText("myBtn2"); myBtn2->move(100,100); int m = 10; //加上mutable修饰符后,可以修改按值传递进来的拷贝 connect(myBtn,&QPushButton::clicked,this,[m] () mutable { m = 20; qDebug() << m; }); // 20 connect(myBtn2,&QPushButton::clicked,this,[=] () { qDebug() << m; }); // 10 qDebug() << m; // 10
-
返回值类型:
[]()->return type{};
int num = []()->int{return 1000;}(); qDebug() << num ;
-
connect与lambda一起使用
//connect与lambda表达式一起用 QPushButton * btn3 = new QPushButton; btn3->setParent(this); btn3->move(200,200); btn3->setText("aaa"); connect(btn3,&QPushButton::clicked,[=](){ btn3->setText("bbb"); this->st->treat("鱼香肉丝"); this->close(); });