电子商务网站建设实训个人总结,个人博客登录首页,佛山市网站建设平台,免费域名注册优惠目录
一、Qt背景介绍
二、搭建Qt开发环境
三、新建工程
四、Qt中的命名规范
五、Qt Creator中的快捷键
六、QWidget基础项目文件详解
6.1 .pro文件解析
6.2 widget.h文件解析
6.3 widget.cpp文件解析
6.4 widget.ui文件解析
6.5 main.cpp文件解析
七、对象树
八、…目录
一、Qt背景介绍
二、搭建Qt开发环境
三、新建工程
四、Qt中的命名规范
五、Qt Creator中的快捷键
六、QWidget基础项目文件详解
6.1 .pro文件解析
6.2 widget.h文件解析
6.3 widget.cpp文件解析
6.4 widget.ui文件解析
6.5 main.cpp文件解析
七、对象树
八、窗口坐标系 一、Qt背景介绍 什么是Qt? Qt是⼀个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供了建立艺术级图形界面所需的所有功能。它是完全面向对象的很容易扩展。Qt为开发者提供了一种基于组件的开发模式开发者可以通过简单的拖拽和组合来实现复杂的应用程序同时也可以使用C语言进行高级开发 图形用户界面指采用图形方式显示的计算机操作用户界面是计算机与其使用者之间的对话接口是计算机系统的重要组成部分 Qt支持的平台 Windows ‒ XP、Vista、Win7、Win8、Win2008、Win10Unix/X11 ‒ Linux、Sun Solaris、HP-UX、Compaq Tru64 UNIX、IBM AIX、SGI IRIX、FreeBSD、BSD/OS、和其他很多X11平台Macintosh ‒ Mac OS XEmbedded ‒ 有帧缓冲支持的嵌入式Linux平台Windows CEAndroid Qt的版本 目前最新的版本是Qt6但是相对来说Qt6和Qt5之间的核心功能区别不大并且企业中也仍然有大量的项目在使用Qt5。因此后续文章上仍然使用Qt5版本来进行介绍
Qt在发布的时候还提供了两种许可证
商业许可开发者以商业目的使用Qt框架进行开发和发布软件的许可开发者需要购买商业许可并按照相关规定使用Qt框架。商业许可提供了更多的功能和服务适合于商业软件开发开源许可开发者以非商业目的使用Qt框架进行开发和发布软件的许可开发者可以免费使用Qt框架但需要遵守开源许可协议的要求如在软件中包含Qt许可协议的声明等 Qt的优点 跨平台几乎支持所有的平台接口简单容易上手学习Qt框架对学习其他框架有参考意义一定程度上简化了内存回收机制开发效率高能够快速的构建应用程序有很好的社区氛围市场份额在缓慢上升可以进行嵌入式开发 Qt的应用场景 桌面应用程序
Qt能够创建各种类型的桌面应用程序包括文件管理器、媒体播放器、绘图程序等。Qt应用程序支持多种操作系统可以运行在Windows、Linux、macOS等桌面操作系统上
移动应用程序
Qt支持Android和IOS移动操作系统为应用程序提供了强大的跨平台能力。可以使用Qt构建各种 移动应用程序。如社交应用、游戏、娱乐等
嵌入式系统
Qt在嵌入式领域应用非常广泛可以构建面向各种设备的图形应用程序在机顶盒、车载娱乐系统、安防监控设备等领域具有广泛的应用 二、搭建Qt开发环境 环境的下载与安装 先去官网下载Qt SDKhttps://download.qt.io/archive/qt/
本文中下载的版本是5.14.2可以自行选择 注意
在双击之前先断网否则需要注册Qt账号登录后才能进入下一步安装安装路径时不能出现中文路径否则即使安装上也无法使用
若电脑磁盘空间允许建议全选以便后续使用若空间不允许请看下图自行选择 Qt环境变量配置 找到Qt的安装路径复制bin路径 鼠标右键此电脑点击属性点击高级系统设置点击环境变量 新建填入bin路径确定 环境变量是在操作系统中一个具有特定名字的对象它包含了⼀个或者多个应用程序将要使用到的信息。如Windows和DOS操作系统中的path环境变量当要求系统运行一个程序而没有告诉它程序所在的完整路径时系统除了在当前目录下面寻找此程序外还会到path中指定的路径中找。 在Windows上设置Qt的环境变量是为了能够在命令行或其他应用程序中直接访问Qt相关的命令和工具 三、新建工程
打开Qt Creator在菜单栏中选中文件新建文件或项目 或者 使用快捷键Ctrln 或者 直接点击new 选择项目模板 新建项目对话框中有五类项目模板
项目模板说明ApplicationQt应用程序包括普通窗体和QtQuick程序Library可创建动态库、静态库、以及Qt Quick扩展插件、Qt Creator自身插件其他项目可以创建单元测试项目Qt4设计师自定义控件、子目录项目Non-Qt-Project非Qt项目可以创建纯C或纯C项目Import Project导入项目。从版本控制系统管理的软件项目中导入旧的项目
一般常用的是第一类Application选择后在右侧会看到Qt应用程序的多个子模板 子模板说明Qt Widgets Application普通窗体模板传统基于部件的窗体界面程序Qt Console ApplicationQt控制台应用程序使用较少Qt for python在Python下用LGPL的许可来开发闭源Qt软件Qt Quick ApplicationQt提供的⼀种高级用户界面技术使用它可以方便快速的为移动以及嵌入式设备开发流畅美观的用户界⾯。Qt Quick模块是开发QML应用的标准库提供了使用QML创建用户界面所需的一切包括可视化、交互、动画、模型、视图、粒子效果以及着色效果等
选择不同的项目模板Qt Creator就会在后续项目创建好了之后生成不同的基础代码 选择构建系统 选择Qt项目的构建系统使用默认的qmake即可 qmakeqmake是⼀个构建工具用于自动生成makefile文件。qmake支持跨平台构建。qmake编辑的是⼀个后缀名为.pro的文件CMakeCMake是⼀个跨平台的构建工具。CMake本身不是⼀个编译器其实就是生成⼀个让编译器能读懂编译流程的文件工具。让CMake自动生成构建系统如Makefile和Visual Studio项目文件。CMake是⼀个第三方工具有自己的文档QbsQbsQt BuildSuiteQt构建套件同qmake、CMake一样都是构建工具。Qbs号称是新⼀代的构建⼯具比qmake编译速度更快。Qbs没有绑定Qt版本它从项目文件的高级项目描述中生成⼀个正确的依赖表。而传统的MakeFile生成工具如qmake和CMake其在生成MakeFile文件后将实际的命令交给Make工具去执行
Qt官方声明因市场原因弃用Qbs。对于Qt用户来说qmake是当前使用最广泛的构建工具CMake其次 类信息设置界面 目前有三种基类可供选择
基类说明QWidget最简单、最基本的窗体程序里面可以放置多个控件实现程序功能QMainWindow主窗口类一般用于较为复杂的应用程序除了中央客户区界面还包括菜单栏、工具栏、状态栏以及多个可停靠的工具对话框QDialog基于对话框的程序对话框一般用户弹窗也可以用于主界面显示。对话框是从QWidget继承而来的并丰富了一些功能如模态显示和返回值等
三个类之间的关系如下图 选择Qt套件 默认只有第⼀个Desktop Qt 5.14.2 MinGW 64-bit若安装配置了多个Qt套件就可以都选上。Qt套件是指Qt程序从编译链接到运行环境的全部工具和Qt类库的集合对于MinGW版本Qt程序生成和调试至少需要MinGW中的编译器g自动调用链接器、g配套的基础库、调器gdb还 有使用MinGW环境编译而成的Qt类库自身。默认情况下在上面Kit Selection里选中全部套件 选择版本控制系统 在项目管理界面可以设置作为子项目以及加入版本控制系统管理。这两个功能暂时用不到都用默认的None然后点击完成 若想把代码提交到码云或者github可以在此处选择git作为版本控制系统 四、Qt中的命名规范
驼峰命名法
类名首字母大写单词和单词之间首字母大写函数名及变量名首字母小写单词和单词之间首字母大写
Qt偏好驼峰命名法这一点不像之前学习的STL偏好蛇形命名如unordered_map等 五、Qt Creator中的快捷键
注释ctrl /运行ctrl R编译ctrl B字体缩放ctrl 鼠标滑轮查找ctrl F整行移动ctrl shift ⬆/⬇帮助文档鼠标定位F1自动对齐ctrl i同名的 .h 和 .cpp 的切换F4生成函数声明的对应定义 alt enterctrl 鼠标左键 跳转定义 Alt键盘方向左键 跳转回来 六、QWidget基础项目文件详解
6.1 .pro文件解析
工程新建好之后在工程目录列表中有一个后缀为.pro的文件即工程文件是qmake自动生成的用于生成makefile的配置文件 双击进入该文件该文件的核心内容如下:
QT core gui
greaterThan(QT_MAJOR_VERSION, 4): QT widgets
CONFIG c11
DEFINES QT_DEPRECATED_WARNINGS
TARGET QtTest
TEMPLATE appSOURCES \main.cpp \widget.cppHEADERS \widget.hFORMS \widget.ui注释从#开始直到该行结束QT core guiQt包含的模块 greaterThan(QT_MAJOR_VERSION, 4): QT widgets
这条语句的含义是若QT_MAJOR_VERSION大于4即当前使用的Qt5及更高版本需要增加widgets模块。若项目仅需支持Qt5也可以直接添加QT widgets⼀句。不过为了保持代码兼容最好还是按照Qt Creator生成的语句编写
CONFIG c11
CONFIG用来告诉qmake关于应用程序的配置信息上述语句说明使用c11的特性
DEFINES QT_DEPRECATED_WARNINGS
定义编译选项。QT_DEPRECATED_WARNINGS表示当Qt的某些功能被标记为过时的那么编译器会发出警告
TARGET QtTest指定生成的应用程序名TEMPLATE app告诉qmake为这个应用程序生成哪种makefile
app建立一个应用程序的makefile默认值若模板没有被指定这个将会被使用lib建立一个库的makefilevcapp建立一个应用程序的VisualStudio项目文件vclib建立一个库的VisualStudio项目文件subdirs这是一个特殊的模板。它可以创建一个能够进入特定目录的makefile并且为它调用make的makefile
工程中包含的源文件SOURCES main.cpp/widget.cpp工程中包含的头文件HEADERS widget.h工程中包含的资源文件RESOURCES painter.qrc工程中包含的ui设计文件FORMS widget.ui 6.2 widget.h文件解析 说明
在Qt中若要使用信号与槽signal和slot的机制就必须加入Q_OBJECT宏Ui::Widget *ui这个指针是用前面声明的namespace Ui中的Widget类定义的不是同一个Widget所以指针ui指向可视化设计的界面后面要访问界面上的组件都需要通过这个指针ui去访问Ui:Widget继承自Ui_Widget类Ui_Widget类位于ui_widget.h文件中ui_widget.h文件是对widget.ui文件编译后自动生成的 6.3 widget.cpp文件解析
widget.cpp文件是类Widget的实现代码所有在窗体上要实现的功能添加在此文件中 6.4 widget.ui文件解析
widget.ui是窗体界面定义文件是一个XML文件定义了窗口上的所有组件的属性设置、布局及其信号与槽函数的关联等。用UI设计器可视化设计的界面都由Qt自动解析并以XML文件的形式保存下来。在设计界面时只需在UI设计器里进行可视化设计即可而不用管widget.ui文件是怎么生成的 6.5 main.cpp文件解析
#include widget.h#include QApplication // Qt系统提供的标准类名声明头⽂件没有.h后缀int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w; //实例化窗⼝对象w.show(); //调⽤show函数显⽰窗⼝return a.exec();
}QApplication为应用程序类QApplication a为应用程序对象有且仅有⼀个QApplication管理图形用户界面应用程序的控制流和主要设置。QApplication是Qt的整个后台管理的命脉。它包含主事件循环在其中来自窗口系统和其它资源的所有事件处理和调度。它也处理应用程序的初始化和结束并且提供对话管理。对于任何一个使用Qt的图形用户界面应用程序都正好存在⼀个QApplication对象而不论这个应用程序在同⼀时间内是不是有0、1、2或更多个窗口a.exec()程序进入消息循环等待对用户输入进行响应。这里main()把控制权转交给QtQt完成事件处理工作当应用程序退出的时候exec()的值就会返回。在exec()中Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件 七、对象树
在Qt中创建很多对象的时候会提供一个parent对象指针这个parent到底是干什么的呢 QObject是以对象树的形式组织起来的 当创建一个QObject对象时会看到QObject的构造函数接收⼀个QObject指针作为参数这个参数就是parent即父对象指针在创建QObject对象时可以提供⼀个其父对象创建的这个QObject对象会自动添加到其父对象的children()列表当父对象析构的时候这个列表中的所有对象也会被析构。注意这里的父对象并不是继承意义上的父类
这种机制在GUI程序设计中相当有用。如一个按钮有一个QShortcut快捷键对象作为其子对象。当删除按钮的时候这个快捷键理应被删除。这是合理的 QWidget是能够在屏幕上显示的一切组件的父类 QWidget继承自QObject因此也继承了这种对象树关系。一个孩子自动地成为父组件的⼀个子组件。因此它会显示在父组件的坐标系统中被父组件的边界剪裁。如当用户关闭⼀个对话框的时候应用程序将其删除我们希望属于这个对话框的按钮、图标等应该⼀起被删除。因为这些都是对话框的子组件我们也可以自己删除子对象它们会自动从其父对象列表中删除。如当删除了一个工具栏时其所在的主窗口会自动将该工具栏从其子对象列表中删除并且自动调整屏幕显示 对象树机制一定程度上解决了内存问题 当一个QObject对象在堆上创建的时候Qt会同时为其创建一个对象树。不过对象树中对象的顺序是没有定义的即销毁这些对象的顺序也是未定义的任何对象树中的QObject对象delete时若这个对象有parent则自动将其从parent的children()列表中删除若有孩子则自动delete每一个孩子。Qt保证没有QObject会被delete两次这是由析构顺序决定的
若QObject在栈上创建Qt保持同样的行为。正常情况下也不会发生什么问题 作为父组件的window和作为子组件的quit都是QObject的子类。这段代码是正确的quit的析构函数不会被调用两次因为标准C要求局部对象的析构顺序应该按照其创建顺序的相反过程。因此这段代码在超出作用域时会先调用quit的析构函数将其从父对象window的子对象列表中删除然后才会再调用window的析构函数 上述代码的析构顺序就有了问题。在上面的代码中作为父对象的window会先被析构因为它是最后一个创建的对象。在析构过程中它会调用子对象列表中每一个对象的析构函数即quit此时就被析构了。然后代码继续执行在window析构之后quit也会被析构因为quit也是⼀个局部变量在超出作用域的时候当然也需要析构。但是这时候已经是第⼆次调用quit的析构函数了C不允许调用两次析构函数因此程序崩溃了 自定义MyPushButton类观察释放过程 mypushbutton.h
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H#include QPushButton
#include QDebugclass MyPushButton : public QPushButton
{Q_OBJECT
public:explicit MyPushButton(QWidget *parent nullptr);~MyPushButton();//添加MyPushButton类的析构函数signals:};#endif // MYPUSHBUTTON_Hmypushbutton.cpp
#include mypushbutton.hMyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
{qDebug() 我的按钮的构造函数被调用;
}MyPushButton::~MyPushButton()
{qDebug() 我的按钮的析构函数被调用;
}widget.h
#include widget.h
#include ui_widget.h
#include mypushbutton.hWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);MyPushButton* button new MyPushButton(this);//传入this,将其设置到对象树中,当窗口关闭时就会自动调用其析构函数button-setText(我的按钮);
}Widget::~Widget()
{qDebug() Widget的析构函数被调用;delete ui;
} 对象树确保的是先释放子节点的内存后释放父节点的内存。而析构函数的调用顺序则不⼀定遵守上述要求因此看到子节点的析构执行顺序反而在父节点析构顺序之后
注意调用析构函数和释放内存并非是同一件事情 总结 Qt的对象树机制虽然在⼀定程度上解决了内存问题但是也引入了⼀些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰一下所以最好从开始就养成良好习惯
注意在Qt中尽量在构造的时候就指定parent对象并且大胆在堆上创建 八、窗口坐标系
坐标体系以左上角度为原点0,0X向右增加Y向下增加
对于嵌套窗口其坐标是相对于父窗口而言的 可以使用代码设置控件在坐标系中的位置
#include widget.h
#include ui_widget.h
#include mypushbutton.h
#include QPushButtonWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);QPushButton* btn1 new QPushButton(按钮1, this);btn1-move(200, 300);QPushButton* btn2 new QPushButton(按钮2, this);qDebug() 按钮1的坐标为[ btn1-x() , btn1-y() ];qDebug() 按钮2的坐标为[ btn2-x() , btn2-y() ];
}Widget::~Widget()
{delete ui;
}
200与300都代表着像素点