目录
什么是QT
特点
QT程序
main函数
QT按钮
纯代码模式
图形化模式
对象树模型
信号和槽
连接与断开
自动连接
断开连接
信号的发射
lambda表达式
基本语法
捕获列表
Lambda表达式用于信号与槽的连接
例如
什么是QT
Qt是一个跨平台的C++图形用户界面应用程序框架。
在QT中,一个函数对应着一个相对应的头文件,文件和函数名相同;
当然了,有的头文件也会隐式包含了其它头文件,所以有些函数不需要特意去包含相对应的头文件
特点
- 跨平台,几乎支持所有的平台
- 接口简单,容易上手,学习QT框架对学习其他框架有参考意义。
- 一定程度上简化了内存回收机制
- 开发效率高,能够快速的构建应用程序。
- 有很好的社区氛围,市场份额在缓慢上升。
- 可以进行嵌入式开发。
QT程序
main函数
QT按钮
QT控件的创建,一般有两种方式:
- 通过图形化的方式,在界面上创建出一个控件,显示设置文本。
- 通过纯代码的方式,通过编写代码,在界面上创建控件,显示设置文本。
纯代码模式
通过代码创建按钮,指定挂到对象树上,方便日后的资源释放
通过按钮对象来调用不同的方法函数来实现不同功能
如果只是创建出对象,是无法显示到窗口中的,所以我们需要依赖一个父窗口,也就是指定一个父亲。(按钮也是继承于QWidget,也属于窗口)。
图形化模式
用图形化模式创建一个按钮,只需要在ui文件内,选择需要的控件拖拽到窗口区即可。
当然,后续还可以添加qrc文件来达到更好的效果。
对象树模型
在Qt中,当一个对象被创建时,可以指定其父对象。
QObject是Qt里边绝大部分类的根类
QObject对象之间是以对象树的形式组织起来的。
- 当两个QObject(或子类)的对象建立了父子关系的时候。子对象就会加入到父对象的一个成员变量叫children(孩子)的list(列表)中。
- 当一个父对象被销毁时,它的所有子对象也会被自动销毁,从而释放它们占用的资源。
对象树确保的是先释放⼦节点的内存, 后释放⽗节点的内存. ⽽析构函数的调⽤顺序则不⼀定遵守上述要求. 因此看到⼦节点的析构执⾏顺序反⽽在⽗节点析构顺序 之后.
注: 调⽤析构函数和释放内存并⾮是同⼀件事。
信号和槽
信号和槽是实现对象间通信的一种机制;
对象在发生信号后,另一个对象可以连接信号到自己的槽函数上,响应。
信号(signals):
- 信号是Qt中的一种特殊函数,它在特定事件发生时被发射(emit)。
- 信号可以携带参数,这些参数在信号发射时传递给连接的槽函数。
槽(Slots):
- 槽是Qt中的一种特殊成员函数,可以连接到信号上。
- 槽函数可以有参数,也可以没有参数。如果有参数,这些参数必须与连接的信号的参数匹配。
连接与断开
自动连接
信号和槽是自动连接的;
两种方式连接:
- 在Qt Designer中,可以通过拖动信号到槽来自动创建连接。
- 也可以在代码中使用 QObject::connect 函数来手动创建连接。
断开连接
使用 QObject::disconnect 函数来断开信号和槽之间的连接。
断开连接可以防止槽函数在不需要的时候被调用。
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//信号源是 图形化按钮 关闭后 谁来处理 怎么处理
connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handclicked);
}
//手动添加 处理图形化pushbutton1槽函数
void Widget::handclicked()
{
this->setWindowTitle("标题修改成标题1");
qDebug()<<"handclicked1";
}
void Widget::handclicked2()
{
//切换原来槽信号后,
this->setWindowTitle("标题修改为2");
qDebug()<<"handclicked2";
}
void Widget::on_pushButton_2_clicked()
{
//1.先断开pushButton原来的 信号槽
//如果没有 disconnect, 就会构成 一个信号绑定了两个槽函数. 触发信号的时候, 两个槽函数都会执行.
disconnect(ui->pushButton,&QPushButton::clicked,this,&Widget::handclicked);
//2.重新绑定信号槽
connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handclicked2);
}
信号的发射
信号的发射是通过调用 emit 关键字实现的。
// myclass.h
signals: // 信号声明部分
void mySignal(int value); // 自定义信号,参数为int类型
// myclass.cpp
#include "myclass.h"
void MyClass::someMethod()
{
int value = 10;
emit mySignal(value); // 发射信号,并传递一个int值
}
#include <QApplication>
#include "myclass.h"
class Receiver : public QObject
{
Q_OBJECT
public slots:
void receiveValue(int value) // 对应的槽函数
{
qDebug() << "Received value:" << value;
}
};
lambda表达式
C++11中的Lambda表达式用于定义匿名的函数对象,以简化编程工作。
基本语法
[捕获列表](参数列表) -> 返回类型 { 函数体 }
[capture-list] (parameters) -> return-type { body; }
- capture-list(捕获列表): 定义了lambda函数体中可以访问的外部变量。可以是空的,或者使用[&]捕获所有外部变量的引用,[=]捕获所有外部变量的值,或者明确指定个别变量,如[x, &y]表示按值捕获x,按引用捕获y。
- parameters(参数列表): 类似于常规函数的参数列表,可以为空。
- -> return-type(返回类型): 可选,明确指定lambda函数的返回类型。如果不写,则编译器会根据函数体推导返回类型。
- body(函数体): 包含了lambda表达式执行的具体代码。
捕获列表
[=]:以传值方式捕获所有局部变量。
[&]:以引用方式捕获所有局部变量。
[变量]:捕获特定变量,可以使用=或&指定捕获方式。
Lambda表达式用于信号与槽的连接
QObject::connect(sender, &SenderClass::signalName, [=]() {
// Lambda表达式内的代码
});
例如
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//lanbda的使用
QPushButton* button = new QPushButton(this);
button->setText("按钮");
button->move(200,200);
//链接
connect(button,&QPushButton::clicked,this,[=](){
qDebug()<<"lambda被执行";
this->setWindowTitle("我是窗口标题");
this->move(100,100);
});
}