目录
1.Qt简介
跨平台图形界面引擎
历史:1991 奇趣科技
优点: 跨平台、接口简单容易上手、一定程度上简化了内存回收
版本: 商业版、开源版
2. 创建第一个QT程序
2.1 一些QT基本文件
1. 点击创建项目后,选择项目路径以及给项目起名称
2. 名称——不能有中文,不能有空格
3. 路径——不能有中文路径
4. 默认创建有窗口类,myWidget,
基类有三种选择:QWidget、QMainWindow、QDialog
其中QWidget为父类,最基础的仅有一个空白窗口
5. main函数: QApplication a; 应用程序对象,有且仅有一个
myWidget w; 实例化窗口对象
w.show() 调用show函数 显示窗口
return a.exec() 让应用程序对象进入消息循环机制,代码阻塞到当前行
main文件
#include "widget.h"
#include <QApplication>
//main 程序入口 argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{
//a应用程序对象, 在QT中,应用程序对象,有且只有一个
QApplication a(argc, argv);
//窗口对象,Widget父类(自己创建的基类名字)->QWidget
Widget w;
//窗口对象 默认不会显示,必须要调用show方法显示窗口
w.show();
//让应用程序对象进入消息循环
//当代码阻塞到这行
return a.exec();
}
.pro文件
QT += core gui //Qt包含的模块,默认包含核心模块和图形模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于四版本以上,包含widget模块
CONFIG += c++11
SOURCES += \ //源文件
main.cpp \
widget.cpp
HEADERS += \ //头文件
widget.h
FORMS += \
widget.ui //图形设计文件
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
.h文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget> //包含头文件 QWidget 窗口类
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT //Q_OBJECT宏,允许类中使用信号和槽的机制
public:
Widget(QWidget *parent = nullptr); //构造函数
~Widget(); //析构函数
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
2.2 命名规范
1.类名:首字母大写,单词和单词之间首字母大写
2.函数名、变量名称: 首字母小写,单词和单词之间首字母大写
2.3 快捷键
注释 ctrl + /
运行 ctrl + r
编译 ctrl + b
字体缩放 ctrl + 滚轮
查找 ctrl + f
整行移动 ctrl + shift + ↑ 或 ↓
帮助文档 F1
自动对齐 ctrl + i;
同名之间的 .h 和 .cpp 之间的切换 F4
3. 常用API
3.1 窗口
resize(x,y) 重置窗口大小
setFixedSize(x,y) 设置固定窗口大小
setWindowTitle(" ") 设置窗口标题
//设置窗口标题
setWindowTitle("第一个窗口");
//重置窗口大小
resize(600,600);
//设置固定窗口大小
setFixedSize(600,600);
3.2 按钮
QPushButton* btn = new QPushButton; 创建一个按钮,没有依赖项是以独立窗口出现
btn->setParent(this) 设置依赖项,即在当前父类窗口里面创建按钮
btn->setText(" ") 设置文本
QPushButton* btn = new QPushButton(" ",this) 通常在创建时就选定好文本和依赖项
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton* btn = new QPushButton("aaa",this);
}
输出结果
4.Qt中的对象树
一定程度上简化了内存回收机制
当创建的对象 指定的父亲是由 QObject 或者 Object 派生的类的时候,这个对象被加载到对象树上,当窗口关闭掉的时候,树上的对象也都会被释放掉
析构的发生是从父类开始(父类析构先调用,寻找子类,若找到就对子类进行相同操作
若没有子类或者已经对子类进行操作了,才对父类进行空间释放)
但释放空间的过程是从子类开始释放
5.Qt中的坐标系
x以右侧为证
y以下侧为正
左上角是(0,0)
6.Qt信号和槽的基本使用
需求:点击按钮关闭窗口
链接 connect(信号发送者,发送的信号,信号的接收者,处理的槽函数)
connect(this->zt,&Teacher::hungry,this->st,&Student::treat);
7.自定义信号和槽
7.1 自定义信号
自定义信号写在 signals下
返回值是void
只需要声明,不需要实现
//可以有参数, 可以发生重载
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
~Teacher();
//自定义的信号要写到signals下
signals:
//返回值是void,只需要声明,不需要实现
//可以有参数,也可以重载
void hungry();
void hungry(QString foodName);
};
7.2 槽
自定义槽函数写在 public 或 全局函数 或 public slots 或 lambda
返回值是 void
需要声明也需要实现
可以有参数,也可以发生重载
class Student : public QObject
{
Q_OBJECT
public slots:
//返回值是void
//需要声明,也需要实现
//可以有参数,可以发生重载
void treat();
void treat(QString foodName);
};
void Student::treat()
{
qDebug() <<"请老师吃饭";
}
void Student::treat(QString foodName)
{
//输出的QString会自动加上双引号,必须转为char* 才能正常输出
//QString 转 char* 方法
//通过.toUtf8() 转为QByteArray类型
//通过.data() 转为char*
qDebug() << "请老师吃:" << foodName.toUtf8().data();
}
7.3 发生重载时
当信号和槽发生重载时,需要利用函数指针来明确指出函数地址
class Student : public QObject
{
Q_OBJECT
public slots:
//返回值是void
//需要声明,也需要实现
//可以有参数,可以发生重载
void treat();
};
class Teacher : public QObject
{
Q_OBJECT
signals:
//返回值是void,只需要声明,不需要实现
//可以有参数,也可以重载
void hungry();
};
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->zt = new Teacher(this);
this->st = new Student(this);
void(Teacher:: *teacherSignal)() = &Teacher::hungry;
void(Student:: *studentSignal)() = &Student::treat;
connect(this->zt,teacherSignal,this->st,studentSignal);
classIsOver1();
//链接有参信号和槽
// 函数指针 可以指向 函数地址
//当存在函数重载时,需要使用函数指针来链接信号和槽
void(Teacher:: *teacherSignal2)(QString) = &Teacher::hungry;
void(Student:: *studentSignal2)(QString) = &Student::treat;
connect(this->zt,teacherSignal2,this->st,studentSignal2);
classIsOver2();
}
void Widget::classIsOver1()
{
//触发自定义信号
emit this->zt->hungry();
}
void Widget::classIsOver2()
{
emit this->zt->hungry("宫保鸡丁");
}
7.4 将 QString 转换为 char*
输出的QString会自动加上双引号,必须转为char* 才能正常输出
QString 转 char* 方法
通过.toUtf8() 转为QByteArray类型
通过.data() 转为char*
void Student::treat(QString foodName)
{
//输出的QString会自动加上双引号,必须转为char* 才能正常输出
//QString 转 char* 方法
//通过.toUtf8() 转为QByteArray类型
//通过.data() 转为char*
qDebug() << "请老师吃:" << foodName.toUtf8().data();
}
7.5 信号和槽拓展
1.信号和信号之间是可以链接的
2.可以断开链接
3.一个信号可以相应多个槽函数
4.多个信号可以链接同一个槽函数
5.信号和槽函数的类型必须一一对应
信号的参数个数 可以多于槽函数的参数个数,反之不可以
6.Lambda函数可以作为槽,可以进行一些函数调用;
this->zt = new Teacher(this);
this->st = new Student(this);
//创建按钮
QPushButton* btn = new QPushButton("下课",this);
resize(600,500);
void(Teacher:: *teacherSignal2)(QString) = &Teacher::hungry;
void(Student:: *studentSignal2)(QString) = &Student::treat;
//1.信号和信号之间是可以链接的 btn发送->this窗口接收(调用hungry) ->zt发送->st接收
connect(btn,&QPushButton::clicked,this,[=](){emit zt->hungry("宫保鸡丁");});
connect(this->zt,teacherSignal2,st,studentSignal2);
//2.可以断开链接
disconnect(btn,&QPushButton::clicked,zt,teacherSignal2);
当点击按钮时st会接收信号,调用treat槽函数
8. Lambda表达式
[](){} 组成
[] 中可以加 = & a &a.. 推荐使用=
[=]函数体内可以使用Lambda所在作用范围内所有可见的局部变量,但不能对变量进行修改
[&]对内部所调用的变量进行引用
[a]函数体内只能使用Lambda所在作用范围内的 a 变量,其他的都不认识
[&a]只认识a,且对a进行引用
() 形参列表
{} 实现体
mutable 拿到对使用变量的拷贝, 加上 mutable 修饰后,可以修改按值传进来的拷贝
-> type 代表lambda表达式的返回值
而且如果把lambda表达式当作槽来使用,通常是this接收,且this可以省略
先创建三个按钮
QPushButton* btn = new QPushButton("aaa",this);
QPushButton* btn2 = new QPushButton("aaa",this);
QPushButton* btn3 = new QPushButton("aaa",this);
btn2->move(100,100);
btn3->move(100,200);
int m = 10;
对lambda表达式的调用
[=](){
btn->setText("bbb");
}();//再{}后加()是对该函数体进行调用;
做为槽的使用
//当进行信号和槽链接时,控件内会进入一个锁的状态,若强行使用[&]来修改,则会使程序终止
connect(btn,&QPushButton::clicked,this,[&](){btn->setText("111");});
//点击按钮,则程序终止,因为使用引用来改变了按钮在外部的值
//但仅仅是调用函数则没问题。
connect(btn2,&QPushButton::clicked,this,[=](){btn2->setText("111");});
//点击按钮,则按钮名字改变,但不改变该按钮在外部的值
//若是进行值传递
connect(btn3,&QPushButton::clicked,this,[=]()mutable{m = 20,qDebug()<<m;});
//点击btn3 输出20;但此时仅仅在内部让拷贝的 m = 20,再将 m 输出,而再外部 m 的值仍为10;
//->返回值类型
int n = [=]()->int{return 100;}();
qDebug()<<n; //输出100;
//点击按钮关闭窗口
connect(btn3,&QPushButton::clicked,this,[=](){this->close();});
//输出20,再关闭窗口