目录
一、创建QT文件
二、目录结构讲解
1、.pro文件
2、源文件与头文件
3、编译运行
4、界面文件
三、梦开始的地方(Hello World!)
1、代码方式
2、拖拽方式
四、Qt中的“容器”
五、Qt的对象树机制
1、对象树的引入
2、对象树的概念讲解
一、创建QT文件
首先我们打开Qt Creator,如下所示;
由于可能大家版本不同,可能有的会是如下界面,不过用法都相同;
我们在欢迎界面中点击创建,会弹出如下如下页面;此时第一列我们选择第一个,表示我们要创建一个应用程序,其中第二个是基于Python的;
然后我们在第二列中我们选择第一个表示我们要创建一个桌面应用程序,第二个表示我们要创建一个控制台的Qt程序;这里我们选择第一个 Qt Widgets Application;
接着会弹出下面这个窗口,我们设置项目名和项目路径,小编这里起的项目名为24_01_28_HelloWorld_1
接着我们要选择编译我们项目的编译器;这里我们选择qmake即可,大部分情况都会选择qmake;
这里我们要为我们接下来创建的窗口程序创建一个类,这里我们选择QWidget作为基类,最基本的窗口程序类;
对于基类的选择,目前有如下三种;如下所示;
QMainWindow:主窗口类,一般用于较为复杂的程序应用,除了中央客户区界面,还包括菜单栏,工具栏,状态栏等多个可停靠的工具对话框等;
QWidget:最简单,最基础的窗体程序,里面可放置多个控件;
QDialog:对话框程序,一般用户弹窗;
这么一介绍,可能还是很懵,不过也很正常,这个在后面学习中可以慢慢体会;
接下来是语言和翻译文件的选择,这里用于国际化软件,一般当我们的软件需要多种语言时,我们才会设置这一栏,这里我们直接点击下一步即可;
这一步时选择编译工具,小编当时安装了很多编译软件,所以这里有多个,这里我们选择一个即可;
选择版本控制系统,这里若你有版本控制可以选择Git,若没有选择None即可;
这样,我们一个完整的项目就创建好了;
我们发现左边项目文件管理区域中会存在三个默认目录,一个是头文件,一个是源文件,还有一个是界面文件;下面我会依次讲解这三个目录下的文件;
二、目录结构讲解
1、.pro文件
首先,我们不难发现的是目录结构中,第一个.pro文件,这个文件就是qmake编译的文件,可以理解成我们之前写过的makefile文件;如下所示;
2、源文件与头文件
我们首先从main.cc这个源文件开始看起;
首先我们需要使用一个QApplication的类,无论是哪个QT程序都需要这个类,我们将命令行参数传递给这个类,接着我们创建一个Widget的类,这个类也就是我们一开始创建的那个类,继承自QWidget,我们通过继承方法show来显示这个控件,同时我们也可以通过hide来隐藏这个控件,最后返回时,我们调用exec方法,这个方法会将程序控制权交给我们的QT,等待用户交互,直至用户想要退出程序后,该函数才会返回;
widget.h文件理解;
widget.cc文件理解;
特别注意的是setupUi主要是绑定界面目录下的Ui文件,是当前类与界面目录下某一Ui文件绑定关系的函数;
3、编译运行
我们可以点击项目页面左下角的三角形编译运行项目;
不一会,我们会发现弹出一个窗口,这个窗口就是我们代码的运行结果;
4、界面文件
我们点击界面文件目录下的widget.ui文件,Qt Creator会帮我们弹出一个设计师页面,我们在这个设计师页面下可以通过手动拖拽的方式开发Qt程序;如下所示;
我们可以通过拖拽的方式将左边控件拖拽到设计师页面中来完成Qt程序的设计,这个过程中会自动生成代码;我们点击左边菜单栏中的编辑回到项目文件中;
此时我们看到的代码才是我们刚才设计师页面中的真实样貌;每当我们进行拖拽时,会自动生成相应的代码;
三、梦开始的地方(Hello World!)
接下来我将用两种方式来编写一个Hello World程序;
1、代码方式
在这之前,首先我向大家介绍一个小控件——QLable;
QLable就是标签控件,与html中的标签类似;我们使用这个控件前,需要引入头文件QLable,在Qt中,一般来说,我们使用的类的头文件与类名同名;
我们在widget.cc文件中,QWidget的构造函数内编写如上代码,我们便完成了一个Hello World程序,其中关于对象树的知识暂时不介绍,还有这个对象必须是new出来的;我们观察一下程序运行结果,如下所示;
2、拖拽方式
我们将刚才写的代码注释掉;然后点击界面文件中的 widget.ui 文件;我们在控件中找到Label;
我们直接可以将控件拖拽到设计师页面中,右下角,我们可以设置控件属性;
到这一步,我们的程序已经完成了,我们直接点运行,如下所示;
四、Qt中的“容器”
在C++中,STL容器的学习是必不可少的,可由于Qt某些历史原因,Qt也实现了自己的一套容器,比如Qt的序列式容器,QString、QList、QLinkedList、QVector、QStack、QQueue;
关联式容器:QMap、QMultiMap、QHash、QMultiHash、QSet;
其接口使用与我们STL容器的使用大体一致,在进行Qt开发中,我们还是仍然建议使用Qt为我们提供的容器;
五、Qt的对象树机制
1、对象树的引入
再次回到我们上述使用代码方式实现Hello World程序的代码;我们将代码中堆上创建的QLabel标签改为在栈上创建,那么会有什么现象发生呢?
我们惊奇的发现,窗口程序上居然什么都没有显示,这是为什么呢?
实际上,这是因为我们由于是在栈上创建的label标签,而我们创建的标签的生命周期随Widget构造函数的生命周期,当我们出Widget构造函数时,此时我们的label对象会自动销毁,所以我们就看不到我们的label标签,这也就是为什么我们在堆上创建label标签,此时创建的label标签不会出构造函数后自动销毁;
由于我们可能会存在大量在堆上创建的对象,这时很难保证每次编写的程序都不会出现内存泄漏的问题,因此此时Qt为我们提供了一套半自动的内存回收机制;既然是半自动,那就肯定不会像Java一样,完全不用我们管内存回收的问题,我们还是的手动操作一下,这就设计我们接下来要讲解的对象树的概念;
2、对象树的概念讲解
Qt是通过对象树来完成资源自动回收,这个对象树,实际上就是一个多叉树;假设我们最开始有一个控件Widget,在这个控件里,我们有三个子控件,而其中一个子控件里,又有两个个子控件,如下所示;
此时我们若给每个控件指定其父控件,这样我们在销毁父控件时,分别找到其子控件,先将子控件销毁后,在销毁父控件,这样,我们就可以减少内存泄漏的发生了;因此,在上述代码中,我们传入this指针,实际上是给我们创建的那个控件指定父控件,形成对象树;