目录
前言:
虽然现在学习了Linux的系统部分,C++,以及部分数据结构,也了解了一下git的相关内容,但是呢,对于向外拓展的方面笔者感觉并不是很充实,对于Qt,对于算法,对于MySQL等都没有具体了解过,所以笔者最近也是突然有了点内驱力了,打算在这个假期更新完Qt,至少咱们更新完能结合数数据库写一个项目,项目的话呢,就是仿QQ音乐的一款播放器吧!其实我是想要仿制酷狗的,后面看吧,其实都一样。
那么本文呢,就开始了对于Qt的一个正式学习,这里打算用两个点来记录,一个点是关于Qt的基本认识,比如历史啊,比如Qt的前置了解知识什么的。第二个点就是第一次创建Qt项目之后的一个解释了,就像我们最开始学习编程的时候打印的第一个Hello World一样。
废话不多说,进入主题吧!
Qt的基础认识
1.Qt是什么?
Qt最初由挪威的Trolltech公司开发,现由Qt公司管理。它是一个面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器,Meta Object Compiler,moc)以及一些宏。Qt提供了丰富的库和工具,使开发者能够更快速、更高效地创建各种类型的软件,如图形用户界面(GUI)程序、嵌入式系统、移动应用和桌面应用程序等。
上文提到的GUI,G代表的是graph,也就是图形,对于图形化介绍来说,基本是给非程序员用户使用的,对于咱们程序员来说,更多的使用的是TUI,比如平常使用的Windows的cmd,就是典型的TUI。在市面上,有一种常见的岗位是前端开发,实际上,前端开发是一个大类,指的是桌面开发,网页开发,移动应用开发,对于Qt来说,更多的是桌面开发,我们也可以理解为桌面开发。
最新的Qt版本是可以开发移动桌面的,但是一般Qt特指开发桌面应用,也就是电脑,对于网页基本上没有Qt什么事。
Qt实际上是一个C++图形化界面应用程序框架,我们主要学习C++的,对于框架这个词语了解的不是很清楚,像隔壁的java来说,对于框架了解的就很清楚的,那么什么是框架呢?
框架嘛,就是一个笼子,看起来好像限制了程序员的自由,但是实际上像我们这种小菜鸡,有了别人写好的框架,我们还管什么自由呢?这本质上是帮助我们写好代码。我们只需要配合这个框架,去填充我们需要的细节就可以了。对于隔壁的Java来说,最常见的框架就是spring,对于C++来说,,框架就没有了,所以写C++的都是牛鬼蛇神,它的生态是割裂的。
对于Qt来说,它的版本分为5和6,这里推荐的是使用5版本,对于6版本实在是有点新了,对于部分公司都还没有应用。
所以我们使用5版本的,这里的官网是:Index of /archive/qt
2.为什么Qt可以保留至今?
那么是否思考过:同样都是编写GUI,为什么Qt能够更胜一筹?
在Windows中,有Windows API可以开发,也有MFC可以开发,也有C#,还有很多很多,为什么Qt能够脱颖而出?这里咱们记住一个点即可,Qt具有很强的跨平台性。部分小点是优化了内存回收机制,还有简单易上手等啥的。
要知道,跨平台可以是Windows,可以是Linux,可以是Mac,可以是嵌入式系统,比如咱们洗衣机的GUI,所以应用层面是十分广泛的。
当然了,具体和其他GUI开发程序的差别,还是推荐各位朋友自己上网查阅资料了。
Qt的环境配置
1.软件安装
对于开发Qt项目,我们需要以下三个东西:
1.C++的编译器,比如g++,cl.exe->请注意,这里是编译器,而不是IDE。
2.Qt SDK也就是Qt的软件开发工具包,但是实际上呢,比如Windows 版本下的Qt SDK,是已经安装好了C++的编译器的,内置的编译器是mingw,是Windows版本的gcc/g++,但是呢,如果我们想要使用vs的cl.exe也不是不行,就是挺难配置的。
3.需要有一个Qt的集成开发环境。有了编译器我们还得要有其他的,对于Qt官方提供的Qt creater是最适合新手的,不需要配置,但是如果你说你想要用visual studio开发Qt项目的话也不是不可以,但是仍然需要额外配置,额外编译,一编译就是一晚上,所以没有必要给自己上强度了。
使用上面的网址安装即可,我们选择
5版本里面的5.14,任意选一个都可以的,再点进去选择我们需要的Windows版本。
安装即可。
可是我们不是说安装三个嘛?实际上,SDK里面包括了第一个编译器,对于我们下载的IDE又包含了SDK,那么我们只需要下一个即可。
下好之后,我们无非注册一个账号,进入了选择我们需要的编译器即可。
2.配置环境变量
相信学习了Linux的朋友们对于环境变量是不陌生的,我们为了之后有更好的体验感,我们需要配置一下环境变量:
在电脑的搜索栏里面搜索环境变量,跳出来的编辑环境变量直接回车,进入到系统属性,对于用户变量和系统变量我们随便选择一个,比如我们一般不会将电脑给别人用吧?在Path里面,将我们刚才安装了Qt的目录里面的bin目录的这个路径复制,直接加上去即可。
以上就是环境的基本配置了。
Qt的项目解释
1.项目基本认识
对于项目来说,我们应该了解部分文件,在搜索栏搜索Assistant并打开文件位置:
我们可以发现有这么多东西,对于第一个Assistant来说,就是文本助手,全英文,当然有中文的,但是我极其不推荐去看中文的,阅读英文文档也是咱们的一个基本技能了。
对于第二个designer,是一个图形化界面的工具,给我们提供了可以直接拖拽控件的方式来管理UI界面。
第三个linguist就是语言管理了,有的时候程序要和国际接轨,那么我们就应该有一种手段一键转换语言,这个工具的作用就是这个。
还有一个在其他文件,应该我不是默认放在C盘的,所以分开了,不过没有影响,最后一个就是creator了,也就是集成开发环境了。
以上是一个基本认识。
2.Qt项目创建
我们要介绍项目得先创建一个项目吧?所以我们先来学习如何创建一个项目,打开Qt creator之后:
在左上角的文件,和vs一样,新建文件:
新建之后出来的是这个,我们选择第一个Application,也就是应用程序,对于其他的我们暂时不考虑,对于Application出现的有Widgets和console,我们使用Qt编译一个GUI程序就选择第一个,Console是控制台,也就是黑框框,即TUI。
相信有人注意到了,后面还有py,这是因为Qt并不是只能由C++开发,它也支持py和java的。对于后面的Quick,是Qt新搞出来的一项技术用来开发GUI的,我们暂时先不了解。
Choose之后进入下一个窗口:
此时我们正式进入到了创建项目,可以看到涉及到了6个点,好像十分麻烦?且听我慢慢介绍,第一个点给你的项目取一个名字,并且设置路径,这不就是VS的创建项目嘛?
第二个点,定义构建系统,有qmake,cmake,Qbs,对于Qbs来说是几乎没有什么人用的,我们就不考虑了,毕竟是新一代的构建工具,对于qmake来说,是老牌的Qt构建工具,对于cmake来说,也不是Qt专属的,很多开源项目都会使用cmake,我们这里选择qmake即可。
那么对于构建系统来说,我们需要了解一个点是元编程,也就是Qt在编译的时候会通过代码生成代码的形式自动的调用一系列的工具,当然,是基于你写的代码,最终生成的代码就是生成的所有的代码的集合了。了解即可。
这里就有意思了,像我们C++是几乎不存在类名必须和文件名一样的说法,隔壁java倒是有,这里有意思的是,如果我们修改class name,也会修改的是Header file 和 Source file 和 form file。
对于form file:
在Qt中,创建GUI的方式有两种,一种是通过代码的方式创建,一种是通过form file,以图形化的方式创建,我们可以通过Qt Designer 和 Qt Creator来编译form file文件。
这里是提前定义好了头文件,源文件,以及form file文件,还有的东西是Base class,这东西在C++的继承里面看起来是不是非常的熟悉?在Qt的元编程技术生成的代码中,生成了一个类,我们要在这个界面选择该类的基类是什么。
对于QMainWindow来说,是一个完整的应用程序窗口,啥都有,对于QWidget来说表示一个控件,QDialog代表一个对话窗口。我们推荐的选择是widget,谁不喜欢自己的东西从0开始呢?我们可以注意到的是Qt中的任何的内置类都是以Q开头的。
这里直接next即可。
下一步就是上文提及到的国际语言了,我们不用管,毕竟我们还没有到那个境界,直接next即可。
这里就是选择哪个SDK了,我们只安装了一个,直接next即可。
这里是让你选择是否进行版本控制,因为我使用了git,所以可以直接添加了。
那么,以上就是所有创建,最后的结果是:
qt就初具雏形了。
3.代码解释
你在这个界面看到的所有东西都是即将解释的,和我们当初学习打印Hello world的时候一样。
1.main.cpp
对于main函数的参数是命令行参数,我们在Linux学习中介绍过,在主函数里面,构建了一个对象QApplication a,接收命令行参数,那么如果想要在Qt中编写一个GUI图形,就必须一个QApplication对象。
那么因为我们刚才填写的类名是mainwindow,所以这里创建了一个对象MainWindow w,它的函数非常好理解,shou和hide,显示和隐藏。这就是创建一个控件对象。对于返回值,exec是不是我们在Linux中的进程替换介绍过?可惜这里一点关系都没有,只是名字恰好是一样的而已。这个函数是用来启动事件的,我们暂时先了解。
2.mainwindows.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
该文件里面的MainWindow是子类,继承的是我们刚才选中的父类,即QWidget,这里的宏是Q_OBJECT,对于这个宏你可真不要小看了,咱给你看看这个宏包括的内容:
内容是非常多的,它涉及到的点是后面的知识点-信号与槽,这是Qt的一个非常核心的机制,如果某个类想要使用信号和槽,就必须引入这个宏。
然后呢就是该类的构造和析构了,对于构造函数来说为什么缺省值是一个空指针呢?这是因为后面使用对象树的时候,定义了一个对象就应该把该对象挂接到一个树上,这个树是我们在数据结构学习的树,不过它不是二叉树,是多叉树。
私有成员是和Form file紧紧相连的。
3.mainwindows.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
对于这里来说,朋友们可能会非常疑惑,明明我的项目里面都没有ui开头的那个头文件,怎么这里要包含呢?
因为该头文件是通过qmake生成的,这是formfile被qmake了,在下面是通过form file生成的界面和widget关联起来。new了之后会在析构函数里面释放。
实现构造函数的时候,我们会发现和ui是非常紧密的。
4.mainwindows.ui
双击进去就是:
左边是内置的空间,右边是属性,此时我们返回编辑:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QWidget" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
</widget>
<resources/>
<connections/>
</ui>
这是一种XML格式,虽然和HTML十分类似,但是XML这里的标签表示的什么含义是程序员自己定义的。我们知道即可。Qt中是通过XML描述界面,进一步的qmake会生成一些C++代码,最后构建完整的界面。
5.Qt_test.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
这个呢就是Qt项目的工程文件了,对于第一行来说,我们后面可能是要修改的。然后是编译版本,这里是C++11.SOURCES到FORMS代表的是有哪些文件参与了编译,这里我们是不用自己修改的,Qt是会自己帮我们维护好的。
这个.pro文件其实和我们之前学习的makefile很类似,qmake搭配.pro文件就可以起到类似的作用。
以上是我们能看到的,那么,你说它和makefile类似,不证明一下吗?
对于上面的文件,都是源文件,如果编译构建Qt项目,构建的过程中还会生成一些中间文件,我们可以看看。
右键.pro文件,在explorer中打开,我们就可以看到这个界面:
然后回退一下:
与该目录并行的一个build目录中间有这么多内容,你看,Makefile是不是在里面?不过这个makefile不是手动写,是qmake自己写好的。
里面的ui的头文件:
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.14.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
void setupUi(QWidget *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 600);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QWidget *MainWindow)
{
MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
就是mianwindows.ui通过xml生成的h文件,里面就是一些方法的实现了。
这些就是Qt自己生成的一些代码了。
以上就是对于Qt的一些基础认识,包括了代码,包括了历史,包括了环境等。
感谢阅读!