创建窗口三大基类
QWidhetQMainWindowQDialog1.1 项目文件介绍mian.cpp 介绍
#include "mywidget.h"#include <QApplication> // QApplication 应用程序类// 程序入口 命令行变量数量 命令行变量数组int main(int argc, char argv[]){ // a 应用程序对象 在Qt中,应用程序对象有且仅有一个 QApplication a(argc, argv); // 窗口类 myWidget w; // 窗口默认不弹出, 使用show类方法显示窗口 w.show(); // a.exec(); 进入消息循环机制 阻塞 return a.exec();}
.pro文件 介绍

注意:如果不知道你在干什么,不要改动.pro文件内容!
!
!
,项目会自动追加,不需要手动填写
#-------------------------------------------------## Project created by QtCreator 2022-07-27T16:11:54##-------------------------------------------------QT += core gui// Qt包含的模块greaterThan(QT_MAJOR_VERSION, 4): QT += widgets// Qt版本大于4,加入widgets模块TARGET = mywidget// 生成的.exe程序名称TEMPLATE = app// 默认应用程序模板SOURCES += \ main.cpp \ // 源文件 mywidget.cppHEADERS += \ mywidget.h// 头文件
mywifget.h文件

#ifndef MYWIDGET_H#define MYWIDGET_H#include <QWidget>class myWidget : public QWidget // 共有继承 从父类Qwidget中{ Q_OBJECT // Q_OBJECT 宏 支持信号和槽public: myWidget(QWidget parent = 0); // 构造函数 parent默认值0 ~myWidget();};#endif // MYWIDGET_H
mywidget.cpp文件
#include "mywidget.h"myWidget::myWidget(QWidget parent) // 基类 : QWidget(parent){}myWidget::~myWidget(){}
Qt开发必备技术栈学习路线和资料
1.2 命名规范类名 首字母大写,单词之间首字母大写
变量名、函数名 首字母小写
1.3 快捷键运行 CTRL + R
编译 CTRL + B
查找 CTRL + F
注释 CTRL + /
帮助文档 F1 、左侧列表中的帮助、C:\Qt\Qt5.9.0\5.9\mingw53_32\bin\assistant.exe
字体缩放 CTRL + 鼠标滚轮
整行代码移动 CTRL + shift + ↑ ↓
自动对齐 CTRL + i
同名之间.h 和.cpp 之间切换 F4
1.4 对象树QObject是Qt里边绝大部分类的根类
QObject对象之间是以对象树的形式组织起来的当两个QObject(或子类)的对象建立了父子关系的时候。子对象就会加入到父对象的一个成员变量叫children(孩子)的list(列表)中。当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里是说父对象和子对象,不要理解成父类和子类)QWidget是能够在屏幕上显示的一切组件的父类QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。我们向某个窗口中添加了一个按钮或者其他控件(建立父子关系),当用户关闭这个窗口的时候,该窗口就会被析构,之前添加到他上边的按钮和其他控件也会被一同析构。这个结果也是我们开发人员所期望的。当然,我们也可以手动删除子对象。当子对象析构的时候会发出一个信号destroyed,父对象收到这个信号之后就会从children列表中将它剔除。比如,当我们删除了一个按钮时,其所在的主窗口会自动将该按钮从其子对象列表(children)中删除,并且自动调整屏幕显示,按钮在屏幕上消失。当这个窗口析构的时候,children列表里边已经没有这个按钮子对象,所以我们手动删除也不会引起程序错误。Qt 引入对象树的概念,在一定程度上简化了内存回收机制,当创建的对象指定的基类时由QObject或者Object派生类的时候,这个对象被加载到对象树上,当窗口关闭时,树上的对象也被释放掉。
对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。
// 设置窗口#include "mywidget.h"#include <QPushButton>myWidget::myWidget(QWidget parent) : QWidget(parent){ // 按钮 QPushButton btn = new QPushButton; // btn->show(); // show() 用顶层的方式弹出 //如果想显示到当前窗口中,需要做依赖,加入对象树中 btn->setParent(this); // this指针就是指向当前类的指针 // 显示文本 btn->setText("德玛西亚"); // 按钮2 声明同时进行初始化 QPushButton btn2 = new QPushButton("Second", this); // 移动btn2,使用重载版本 btn2->move(100, 100); // 配置窗口大小 resize(600, 400); //设置窗口固定大小,设置后不可以通过拖拽调整窗口大小 setFixedSize(600,600); // 按钮配置大小 btn->resize(200, 100); // 指定窗口标题 setWindowTitle("第一个窗口"); // 创建自定义按钮 MyPushButton myBtn = new MyPushButton; myBtn->setParent(this); myBtn->setText("我的按钮"); myBtn->move(200,200);}myWidget::~myWidget(){ // 先调用子对象的析构函数,再调用父对象的析构函数, // 但是打印时可能会出现先打印父对象析构执行提示,但是父对象还未释放完毕。再打印子对象析构执行提示 qDebug() << "MyWidget 析构调用。";}
1.5 坐标系
坐标系左上角为(0,0),向右x为正,向下y为正。
1.6 信号槽信号:各种事件
槽:响应信号的动作
当某个事件发生后,如某个按钮被点击了一下,就会发出一个被点击的信号(signal)。
某个对象接受到这个信号之后,就会做出一些相关的处理动作(称为槽slot)。
但是Qt对象不会无缘无故的收到某个信号,要想让一个对象收到另一个对象发出的信号,这时候需要建立连接(connect)。
1.6.1 系统自带的信号和槽connect 函数是建立信号发送者、信号、信号接收者、槽 四者关系的函数:
connect (sender, signal, receiver, slot);
参数:sender : 信号发送者signal :信号receiver :信号接收者slot :接受对象在收到信号之后所需要调用的函数(槽函数)注意:四个参数均为指针类型,信号和槽是函数指针。
// 创建一个关闭按钮QPushButton quitBtn = new QPushButton("关闭窗口", this);// 信号槽的使用connect(quitBtn, &QPushButton::clicked, this, &MyWidget::close);
利用帮助文档,输入QPushButton,在Content中寻找signal。如果没有就去父类中寻找该关键字。
1.6.2 自定义信号和槽自定义信号使用条件自定义信号声明在类的signals域下没有返回值,为void类型的函数只有函数声明,没有定义可以有参数,可以重载通过emit关键字来触发信号,形式:emit object->sig(参数);自定义槽函数使用条件qt4 必须声明在 private/public/protected slots域下面,qt5之后可以声明public下,同时还可以是静态的成员函数,全局函数,lambda表达式没有返回值,void类型的函数不仅有声明,还得要有实现可以有参数,可以重载案例:
定义场景:下课了,老师跟同学说肚子饿了(信号),学生请老师吃饭(槽)
首先定义一个学生类和老师类;
老师类中声明信号 饿了 hungry
// teacher.h signal:void hungry();
学生类中声明槽函数 请客 treat 并实现
// student.hpublic slot:void treat();// student.cpp 槽函数实现void Student::treat(){ qDebug() << "请老师吃饭";}
在窗口中声明一个公共方法下课,这个方法的调用会触发老师饿了这个信号,而响应槽函数学生请客
// widget.h 声明public:void ClassIsOver();// widget.cpp 实现void MyWidget::ClassIsOver(){ // 触发自定义信号 emit teacher->hungry();}
学生响应了槽函数,并且打印信息
// student.cpp 自定义槽函数void Student::treat(){ qDebug() << "Student treat teacher";}
在窗口连接信号槽
// widget.hzt = new Teacher(this);st = new Student(this);// 连接connect(zt, &Teacher::hungry, st, &Student::treat);// 触发下课函数ClassIsOver();
但是如果有两个重名的信号和自定义的信号的槽,直接连接会报错,所以需要利用函数指针来指向函数地址再连接
// 函数指针void (Teacher:: teacherSingal)(QString) = &Teacher:: hangry;void (Student:: studentSlot)(QString) = &Student::treat;// 连接connect(teacher,teacherSingal,student,studentSlot);
QString 转 char
// QString 转 char // 先转QByteArray 再转到charfoodName.toUTF8().data();
信号和槽的拓展一个信号可以和多个槽相连多个信号可以连接到一个槽一个信号可以连接到另外的一个信号新建一个btn,实现点击发送下课信号到Teacher类,再将老师饿了信号发送到Student类。connect(btn,&QPushButton::clicked,teacher,&Teacher::hungry);信号和槽可以断开连接
disconnect (sender, signal, receiver, slot);
这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。
信号和槽函数参数类型和个数必须同时满足两个条件信号函数的参数个数必须大于等于槽函数的参数个数信号函数的参数类型和槽函数的参数类型必须一一对应文章转自博客园(Happinesspill):https://www.cnblogs.com/happinesspills/p/16542195.html
Qt开发必备技术栈学习路线和资料