前言
作者:小蜗牛向前冲
名言:我可以接受失败,但我不能接受放弃
如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正
目录
一、Qt的基本常识
1、什么是Qt
2、Qt的开发环境
3、Qt 环境变量配置
二、快速上手QT
1、创建项目
2、初始代码解析
3、二种实现hello world的方式
三、认识对象模型(对象树)
1、认识对象树
2、验证对象树
本期学习:什么是Qt,快速打印hello world的二种方法,对象树是什么。
一、Qt的基本常识
1、什么是Qt
Qt是一个跨平台的应用程序框架,广泛用于开发图形用户界面应用程序(GUI应用程序),同时也非常适合用于开发非GUI程序,如命令行工具和服务器。Qt是由挪威的Trolltech公司(现为Qt公司,属于Digia)最初开发的,现在它被许多开发者在世界各地使用。Qt是基于C++的,但也提供了与其他编程语言的绑定,如Python、Ruby和Java等。
主要特点:
跨平台性:Qt可以在多种操作系统上运行,包括Windows、Mac OS、Linux、iOS和Android,使得开发的应用能够在这些平台上无缝运行而无需修改源代码。
丰富的库支持:Qt提供了广泛的库,从基本的数据结构和IO操作到网络通信和复杂的用户界面设计。它包括工具用于数据库交互、XML解析、文件和网络IO、以及多线程编程等。
信号与槽机制:Qt的信号和槽机制是一种高级的事件处理系统,允许创建高度可定制的API和强大的事件处理逻辑,而无需回调函数。
元对象系统:Qt具备一个运行时类型信息系统、动态属性系统和一个强大的事件系统。元对象系统是Qt的核心特性之一,它使得信号和槽机制以及Qt的很多其他功能成为可能。
工具和IDE:Qt提供了一整套工具来辅助开发,包括Qt Designer(一个拖放式界面设计工具)和Qt Creator(一个功能丰富的集成开发环境)。
这里补充一下:与用户交互的二种模式
- 命令行界面/终端界面--TUI(Text-based User Interface)
- 图像化界面--GUI (Graphical User Interface)
2、Qt的开发环境
Qt ⽀持多种开发⼯具,其中⽐较常⽤的开发⼯具有:Qt Creator、Visual Studio、Eclipse.
在后面的开发中我们用Qt Creator进行开发。
Qt Creator 是⼀个轻量级的跨平台集成开发环境(IDE),专为使⽤ Qt 框架进⾏应⽤程序开发⽽设 计。(也是官方提供)
QT SDK(Qt Software Development Kit)是一个用于开发应用程序的工具集,主要面向使用Qt库的开发者。Qt是一种跨平台的应用程序框架,被广泛用于开发图形用户界面应用程序,也可以用来开发非GUI程序如控制台工具和服务器。QT SDK提供了一系列工具,帮助开发者设计、编码、测试、调试和发布基于Qt的软件。
这里我们只要完成对QT SDK的安装就可以完成环境的搭建
Qt 下载官⽹:http://download.qt.io/archive/qt/(下载非常慢,建议科学上网)
国内清华源: https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/
安装成功后双击QT Creator出现下面界面就是安装成功了
其中我们安装完成DSK后,除了有QT Creator外,还会有上面的工具:
Assistant:这是QT自带的离线的官方文档
Designer:这是QT设计师图像化界面的工具,搭配QT Creator使用
Linguis:QT语言家,对接国外业务用的(启到一键切换语言的作用)
QT Creator:这是我们要用到的集成开发环境
3、Qt 环境变量配置
为什么要设置环境变量 环境变量是在操作系统中⼀个具有特定名字的对象,它包含了⼀个或者多个应⽤程序将要使 ⽤到的信息。
例如Windows 和 DOS 操作系统中的 path 环境变量,当要求系统运⾏⼀个程序⽽没有告诉它 程序所在的完整路径时,系统除了在当前⽬录下⾯寻找此程序外,还会到 path 中指定的路径 去找。
在 Windows 上设置 Qt 的环境变量是为了能够在命令⾏或其他应⽤程序中直接访问 Qt 相关 的命令和⼯具。
找到Qt的安装路径,复制 "bin" 路径;
"此电脑" ------> ⿏标右键, "属性" ------> "⾼级系统设置" ------> "环境变量"
"新建" ------> 填⼊ "bin" 路径 ------> "确定" ;
二、快速上手QT
1、创建项目
当我们要选择用QT写开发一个GUI程序就选择下图箭头指的方向就好,其中传统的QT开发GUI的方式就叫做Qt Widgets
文件放置位置
这个是QT的构建工具,我们选择qmake就好了
- qmake: qmake 是⼀个构建⼯具(build tool),⽤于⾃动⽣成 makefile ⽂件。qmake ⽀持跨平 台构建。qmake 编辑的是⼀个后缀名为 .pro 的⽂件
因为我们知道QT其实就是一个框架,当我们使用QT就是在这个框架上进行编写,但我们选择 建立项目就会自动帮助我们生成一下代码,这些代码主要继承下面三个基类。
对于基类的选择,⽬前有三种基类:
- QMainWindo w:主窗⼝类,⼀般⽤于较为复杂的应⽤程序,除了中央客⼾区界⾯,还包括菜单栏、⼯具栏、 状态栏以及多个可停靠的⼯具对话框等。
- QWidget:最简单、最基本的窗体程序,⾥⾯可以放置多个控件实现程序功能
- QDialog:基于对话框的程序,对话框⼀般⽤于弹窗,也可以⽤于主界⾯显⽰。对话框是从QWidget继 承⽽来的,并丰富了⼀些功能,如模态显⽰和返回值等
上述三个类之间的关系如下图:
图上有一个from filef非常关键QT创建图像化界面的方式有二种:
直接通过C++代码创建
通过from filem,以图像化的方式,生成界面(可通过QT Designer或者QT Creaor进行ui文件的编写)
后面大家暂时不用了解,一直下一步就好了。
2、初始代码解析
对于一个刚刚生成的项目,无法就是有头文件,源文件和from file文件组成
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);//这里是为了编写一个Qt,图像化界面,而存在的 QApplication对象
Widget w;//创建文件时候,定义的类
w.show();//创建一个控件对象,并显示出来,.hide指隐藏起来
return a.exec();//让程序执行起来
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);//把from file生成的界面和widget关联起来
}
Widget::~Widget()
{
delete ui;
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT//厷,为了引入Qt的槽和信号
public:
Widget(QWidget *parent = nullptr);//往对象树中,挂入对象,要指定父节点
~Widget();
private:
Ui::Widget *ui;//和from file有关
};
#endif // WIDGET_H
双击froms目录下的widget.ui就会进入图形化界面编辑器,左侧就是Qt的控件,直接拖拽使用。
点击编辑就是ui的本体,这是一种xml,这里和html非常相似都是使用成对的标签显示数据
3、二种实现hello world的方式
方法一:通过图形化界面的方式,创建控件打印:
首先进入ui图像化界面模式,找到Label控件,拖拽到图像区域输入hellow world!!!
方法二、代码实现:在widget.cpp中
#include "widget.h"
#include "ui_widget.h"
#include"QLabel"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);//把from file生成的界面和widget关联起来
QLabel* label = new QLabel(this);//即可在堆上创建,也可以在栈上创建
label->setText("hello world!!!");//这里其实隐式构造了QString
}
Widget::~Widget()
{
delete ui;
}
这里不知道大家注意到一个细节没有,这里我们并没有让,去delele我们new出来的空间,但是在qt这样是不会找内存泄露的,因为我们把这个对象挂到了对象树中去,对象树会帮助我们在合适的时机释放空间的。
三、认识对象模型(对象树)
1、认识对象树
在Qt中,每个对象都可以有一个父对象(parent)和多个子对象(children)。当一个对象被创建时,你可以指定它的父对象。一旦父对象被销毁,所有它的子对象也会被自动销毁。这样,开发者就不需要手动管理每个对象的内存,降低了内存泄漏的风险。
其实对象树的本质就是一课N叉树:
2、验证对象树
为了测试对象树的析构,这里我们显示的打印一下析构过程,这里我们也要重新定义一下我们的
然后选择我们要继承的类QLabel
在 Qt Creator 中, 可以通过 F4 切换头文件和对应的 .cpp 文件
完成对应头文件和.cpp文件的编写
mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QWidget>
#include<QLabel>
class MyLabel : public QLabel
{
Q_OBJECT
public:
MyLabel(QWidget* parent);
~MyLabel();//这里只要按alt+enter,就会在.cpp生成析构函数
};
#endif // MYLABEL_H
mylabel.cpp
#include "mylabel.h"
#include<iostream>
MyLabel::MyLabel(QWidget* parent): QLabel(parent)
{
}
MyLabel::~MyLabel()
{
std::cout << "MyLabel 被销毁!!!" << std::endl;
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<mylabel.h>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
MyLabel* label = new MyLabel(this);
label->setText("hello world!!!");
}
Widget::~Widget()
{
delete ui;
}
运行后,当我们擦掉图像化界面,对象树就会调用析构函数。
虽然我们看到成功调用了析构函数,但是为什么打印出来是乱码,其实这是因为,代码对于生成的是utf8字符集,但是qt终端界面是gbk字符集去解析所以会出现乱码。
为解决这些问题,qt不仅仅为我们提供了QString,可以帮助我们处理编码方式,也提供了专门打印日志的qDeBug()工具
#include "mylabel.h"
#include<iostream>
#include"QDebug"
MyLabel::MyLabel(QWidget* parent): QLabel(parent)
{
}
MyLabel::~MyLabel()
{
qDebug() << "MyLabel 被销毁!!!";
}
后续再 Qt 中,如果想通过打印日志的方式,输出一些调试信息,都优先使用 qDebug. 虽然使用 cout 也行,但是 cout 对于编码的处理不太好,在windows 上容易出现乱码(如果是 Linux 使用 Qt Creator, 一般就没事了,Linux 默认的编码一般都是 utf8)
使用 qDebug,还有一个好处~~ 打印的调试日志,是可以统一进行关闭的!!输出的日志,是开发阶段, 调试程序的时候,使用的,如果你的程序发布给用户,不希望用户看到这些日志的!!qDebug 可以通过编译开关,来实现一键式关闭