文章目录
由于每次代码都是在原有程序上修改,因此除了新建项目,不然一般会在学完后统一展示代码。
提示:具体项目创建流程和注意事项见
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;
}
);
2. 信号
- 信号属于谁,谁就发出信号。
- 按钮只是触发一个软件中断,调用函数,具体函数的功能自己设定。
三、代码(两个独立窗口切换,带参数的信号,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,"我是子窗口");
}