文章目录
一、带参数的信号
1. 基本知识点和操作
2. 运行结果
二、Lambda 表达式和信号
1. Lambda 表达式 (重点)
1.1 信号中无参数
1.2 信号中有参数
2. 信号
三、代码(两个独立窗口切换,带参数的信号,Lambad表达式)
1. 主窗口头文件 —— widget.h
2. 主窗口源文件 —— widget.cpp
3. 子窗口头文件 —— subwidget.h
4. 子窗口源文件 —— subwidget.cpp
由于每次代码都是在原有程序上修改,因此除了新建项目,不然一般会在学完后统一展示代码。
提示:具体项目创建流程和注意事项见
QT 学习笔记(一)
提示:具体项目准备工作和细节讲解见
QT 学习笔记(二)
一、带参数的信号
1. 基本知识点和操作
知识点补充:类的成员函数有个特殊的指针 this ,哪个对象调用这个成员函数, this 就指向这个对象,它可以操作类型任意的成员。
知识点补充:快捷键 f4 可以快速在对应的头文件和源文件进行切换。
因为信号带有了参数,所以对应的槽函数也要带有与信号一 一对应的参数。信号第一个是 int 型,那我的槽函数第一个也必须是 int 型,信号有几个参数,那我的槽函数也必须有几个参数。
打印时,使用 qDebug() ,注意添加 QDebug 头文件,qDebug() 的使用与 C++ 的 cout 相同。
要注意头文件是 QDebug ,打印使用的函数是 qDebug(),还得带括号。
此时,代码这里会出现编译错误,主要是 因为有两个信号,一个不带参数,一个带参数,信号发生了重载, connect 函数不知道应该调用哪一个信号。
对此,我们通过给对应信号进行重新定义解决。如图:(也可以在子窗口头文件当中修改声明信号函数名)
- 打印输出时,如果汉字无法正常输出,通过 str.toUtf8() 函数可以转换为字节数组 QByteArray 。
- data() ——> QByteArray ——> char * 。
- 以上对于多信号函数的处理可能略显麻烦,对此,可以采用 QT4 信号连接,如下图:
此操作虽然容易进行操作,但是 SIGNAL SLOT 将函数名字转变为字符串,不进行报错,只能在运行时才能发现错误。
2. 运行结果
二、Lambda 表达式和信号
1. Lambda 表达式 (重点)
- Lambda 表达式,匿名函数对象是 C++11 增加的新特性,因此在 QT 当中使用需要添加项目文件:CQNFIG += C++11。
- QT 配合信号一起使用,非常方便。
- Lambda 表达式会自动调用槽函数,不需要对槽函数进行定义。
1.1 信号中无参数
- 通过定义一个按钮 Lambda表达式,进行点击按钮输出 1111111 。
QPushButton *b4=new QPushButton(this); b4->setText("Lambda表达式"); b4->move(200,200); connect(b4,&QPushButton::released, // = :把外部所有局部变量、类中所有成员以值传递方式 // this :类中所有成员以值传递方式 // & : 把外部所有局部变量,引用符号 [=]() mutable { b4->setText("123"); qDebug()<<"1111111"; qDebug()<< a << b; a=11; } );
[] 的作用是把外部变量传进来,点击按钮,released 会直接调用 {} 重点内容。
[] 当中 = 的作用是把外部所有局部变量、类中所有成员以值传递方式,但弊端都是只读,不能修改。可以在 [] () 后添加 mutable 解决。
[] 当中 this :类中所有成员以值传递方式。
[] 当中 & : 把外部所有局部变量,引用符号。
1.2 信号中有参数
- Lambda 表达式整个与无参数信号相同,其中 () 的作用是添加信号参数,因此无参数信号当中 () 为空。
- 当点击按钮时,会给 isCheck 传递一个参数(因其是 bool 型,故只有 true 和 false 两种。
//有参数信号 connect(b4,&QPushButton::clicked, // = :把外部所有局部变量、类中所有成员以值传递方式 // this :类中所有成员以值传递方式 // & : 把外部所有局部变量,引用符号 [=](bool isCheck) { qDebug()<< isCheck; } );
. 信号
- 信号属于谁,谁就发出信号。
- 按钮只是触发一个软件中断,调用函数,具体函数的功能自己设定。
三、代码(两个独立窗口切换,带参数的信号,Lambad表达式)
1. 主窗口头文件 —— widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPushButton> #include <QDebug> #include "subwidget.h" //子窗口头文件 class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); //public slots: void changewin(); //改变窗口 void dealsub(); //处理子窗口信号 void dealslot(int,QString); //处理子窗口带参数信号 private: QPushButton a; subwidget subwin; }; #endif // WIDGET_H
2. 主窗口源文件 —— widget.cpp
#include "widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) { setWindowTitle("老大"); //this->setWindowTitle("老大"); a.setParent(this); a.setText("切换到子窗口"); a.move(150,150); //显示子窗口 //subwin.show(); connect(&a,&QPushButton::released,this,&Widget::changewin); //处理子窗口的信号 void(subwidget::*funsignal)()=&subwidget::mysignal; connect(&subwin,funsignal,this,&Widget::dealsub); //处理子窗口的带参数信号 void (subwidget::*testsignal)(int,QString)= &subwidget::mysignal; connect(&subwin,testsignal,this,&Widget::dealslot); // QT4 信号连接 // QT4 槽函数必须要有 slots 关键字修饰。 //connect(&subwin,SIGNAL(mysignal()),this,SLOT(dealsub())); //connect(&subwin,SIGNAL(mysignal(int,QString)),this,SLOT(dealsub())); // Lambda表达式,匿名函数对象 // C++11 增加的新特性,因此在 QT 当中使用需要添加项目文件:CQNFIG += C++11。 // QT 配合信号一起使用,非常方便。 QPushButton *b4=new QPushButton(this); b4->setText("Lambda表达式"); b4->move(200,200); int a=10,b=100; //无参数信号 /* connect(b4,&QPushButton::released, // = :把外部所有局部变量、类中所有成员以值传递方式 // this :类中所有成员以值传递方式 // & : 把外部所有局部变量,引用符号 [=]() mutable { b4->setText("123"); qDebug()<<"1111111"; qDebug()<< a << b; a=11; } );*/ //有参数信号 connect(b4,&QPushButton::clicked, // = :把外部所有局部变量、类中所有成员以值传递方式 // this :类中所有成员以值传递方式 // & : 把外部所有局部变量,引用符号 [=](bool isCheck) { qDebug()<< isCheck; } ); //定义窗口大小 resize(400,300); } void Widget::dealslot(int a, QString str) { qDebug() << a<<str.toUtf8().data(); } void Widget::changewin() { //子窗口显示 subwin.show(); //本窗口隐藏 this->hide(); } void Widget::dealsub() { //主窗口显示 this->show(); //子窗口隐藏 subwin.hide(); } Widget::~Widget() { }
3. 子窗口头文件 —— subwidget.h
#ifndef SUBWIDGET_H #define SUBWIDGET_H #include <QWidget> #include <QPushButton> class subwidget : public QWidget { Q_OBJECT public: explicit subwidget(QWidget *parent = nullptr); void setslot(); //发送信号 signals: void mysignal(); void mysignal(int,QString); public slots: private: QPushButton b; }; #endif // SUBWIDGET_H
4. 子窗口源文件 —— subwidget.cpp
#include "subwidget.h" subwidget::subwidget(QWidget *parent) : QWidget(parent) { this->setWindowTitle("小弟"); b.setParent(this); b.setText("切换到主窗口"); b.move(150,150); connect(&b,&QPushButton::released,this,&subwidget::setslot); resize(400,300); } void subwidget::setslot() { emit mysignal(); emit mysignal(250,"我是子窗口"); }