注意: 项目创建,名称和路径不能包含中文路径。
创建窗口三大基类
mian.cpp 介绍
#include "mywidget.h"
#include // 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 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()
{
}
类名 首字母大写,单词之间首字母大写
**变量名、函数名 **首字母小写
运行 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
QObject是Qt里边绝大部分类的根类
QObject对象之间是以对象树的形式组织起来的
QWidget是能够在屏幕上显示的一切组件的父类
Qt 引入对象树的概念,在一定程度上简化了内存回收机制,当创建的对象指定的基类时由QObject或者Object派生类的时候,这个对象被加载到对象树上,当窗口关闭时,树上的对象也被释放掉。
对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。
// 设置窗口
#include "mywidget.h"
#include 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 析构调用。";
}
坐标系左上角为(0,0),向右x为正,向下y为正。
信号:各种事件
槽:响应信号的动作
当某个事件发生后,如某个按钮被点击了一下,就会发出一个被点击的信号(signal)。
某个对象接受到这个信号之后,就会做出一些相关的处理动作(称为槽slot)。
但是Qt对象不会无缘无故的收到某个信号,要想让一个对象收到另一个对象发出的信号,这时候需要建立连接(connect)。
1.6.1 系统自带的信号和槽
connect 函数是建立信号发送者、信号、信号接收者、槽 四者关系的函数:
connect (sender, signal, receiver, slot);
注意:四个参数均为指针类型,信号和槽是函数指针。
// 创建一个关闭按钮
QPushButton *quitBtn = new QPushButton("关闭窗口", this);
// 信号槽的使用
connect(quitBtn, &QPushButton::clicked, this, &MyWidget::close);
利用帮助文档,输入QPushButton,在Content中寻找signal。如果没有就去父类中寻找该关键字。
在QAbstractButton中可以找到信号关键字,系统自带的信号有如下几个:
1.6.2 自定义信号和槽
自定义信号使用条件
emit object->sig(参数);
自定义槽函数使用条件
qt4 必须声明在 private/public/protected slots域下面,qt5之后可以声明public下,同时还可以是静态的成员函数,全局函数,lambda表达式
没有返回值,void类型的函数
不仅有声明,还得要有实现
可以有参数,可以重载
案例:
定义场景:下课了,老师跟同学说肚子饿了(信号),学生请老师吃饭(槽)
首先定义一个学生类和老师类;
老师类中声明信号 饿了 hungry
// teacher.hsignal: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.h
zt = 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 再转到char*
foodName.toUTF8().data();
信号和槽的拓展
一个信号可以和多个槽相连
多个信号可以连接到一个槽
一个信号可以连接到另外的一个信号
新建一个btn,实现点击发送下课信号到Teacher类,再将老师饿了信号发送到Student类。
connect(btn,&QPushButton::clicked,teacher,&Teacher::hungry);
信号和槽可以断开连接
disconnect (sender, signal, receiver, slot);
这种情况并不经常出现,因为当一个对象****delete之后,Qt自动取消所有连接到这个对象上面的槽。