我的QT5学习之路(二)——第一个程序
一、前言
“工欲善其事,必先利其器”,上一节,我介绍了Qt的安装和配置方法,搭建了基本的开发平台。这一节,来通过一个简单的例子来了解Qt的编程样式和规范,开始喽~~~
二、第一个程序——Hello World
首先,我们可以按照上一节的方法建立一个新的工程,工程的名字可以就叫做Hello,随你的便。在创建工程的过程中,有一个选择是否创建视图界面的选项,这个可以先不选择,因为我们现在只是了解Qt的机制,不需要Qt帮我们做太多的事情,创建完成后,打开main.cpp。

我做的工作主要就是:
1、屏蔽掉程序自己的对话框程序代码;
2、添加一个label控件,并给他传一个文本值,最后显示。
最后的显示结果:

其次,我们来分析一下Qt的基本流程。1~3行是头文件包含,这里有两种头文件,第一种是自定义头文件或者本地头文件,用“ ”来进行表示和包含;第二种是系统头文件,这里就是Qt自带的头文件,直接用<>进行表示和包含就可以。第7行是创建一个QApplication的实例,对于 Qt 程序来说,main()函数一般以创建 application 对象(GUI 程序是QApplication,非 GUI 程序是QCoreApplication。QApplication实际上是QCoreApplication的子类。),这个对象用于管理 Qt 程序的生命周期,开启事件循环。10~11行是核心代码,也就是我们实际添加的用例代码,这里我创建了一个QLabel,利用构造函数对其进行赋值操作,最后调用show方法将其显示出来。最后一行调用exec,开启事件循环(可以理解成一段无线循环)。
写完这两句代码之后,我们想一个问题,这里我们先不讨论Qt的消息机制和其他的通信原理,单纯从C++方面考虑程序的稳定性和鲁棒性。
问题1:我创建的QLabel是创建在栈上的还是堆上的?
问题2:如果我把QLabel变量创建为堆上变量,应该注意哪些问题?
我们先来讨论问题1,这个应该没有什么争议,Qlabel变量是创建在栈上的。再来看看问题2,如果我因为某些需求将变量声明为堆上变量,那么这个时候我就要给这个变量分配空间。这个时候问题就来了,分配空间了,程序结束后谁来释放啊?内存泄露了怎么办啊?怎么能够防止内存泄露啊?如果我们对其不管不顾,在程序结束后,操作系统会将其回收,但是,我们看到label 是建立在堆上的,app 是建立在栈上的。这意味着,label 会在 app 之后析构。也就是说,label 的生命周期长于 app 的生命周期。这可是 Qt 编程的大忌。因为在 Qt 中,所有的QPaintDevice必须要在有QApplication实例的情况下创建和使用。大家好奇的话,可以提一句,QLabel继承自QWidget,QWidget则是QPaintDevice的子类。之所以上面的代码不会有问题,是因为 app 退出时,label 已经关闭,这样的话,label 的所有QPaintDevice一般都不会被访问到了。但是,如果我们的程序,在 app 退出时,组件却没有关闭,这就会造成程序崩溃。
此外,这里的程序没有崩溃的另一个原因是如果在主函数结尾,可以不释放;在其它区域结尾,new出来的内存是逆序释放的,这是c++标准的规定。
这个时候,或许知道C++11标准的童鞋想到了智能指针。没错,智能指针是可以作为指针的托管类来实现指针的自动释放,但是智能指针如果用不好同样会产生各种各样的问题,因此,建议刚开始学习的同学,能不用堆上变量就先不要用,如果真要用的话,记得想好内容溢出和泄露的问题并采取必要的预防办法或者不使用智能指针,给变量添加属性。
label->setAttribute(Qt::WA_DeleteOnClose);
这时,我们回头去看exec方法,因为如此,我们在栈上构建了QLabel对象,却能够一直显示在那里(试想,如果不是无限循环,main()函数立刻会退出,QLabel对象当然也就直接析构了)。
最后,为大家附上堆上变量和智能指针的声明方式,仅供参考。
2.1 堆上代码参考
#include<QApplication>
#include<QLabel> int main(int argc ,char **argv)
{
QApplication a(argc,argv);
QLabel *label =new QLabel("Hello world");
label->show(); return a.exec();
}
2.2 智能指针代码参考(Sailfish OS)
#include <QApplication> int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(new QApplication(argc, argv));
QScopedPointer<QQuickView> view(new QQuickView);
view->setSource("/path/to/main.qml");
...
return app->exec();
}
三、我的观点
关于指针的使用方式和地方的选择这个确实是见仁见智的,我自己对于指针的使用是很小心的,如果使用的话也会在一些不牵扯线程安全的情况下使用,并且打印日志报告。另外一个问题就是指针的释放和重用问题,我的观点是如果在指针被释放的作用域进行delete的操作,但是并没有置为null,这个时候指针应该是还能够使用的,只是没有交还给操作系统而已,如有误解,请指正。
我的QT5学习之路(二)——第一个程序的更多相关文章
- IOS学习之路二十(程序json转换数据的中文字符问题解决)
ios请求web中的json数据的时候经常出现乱码问题: 例如请求结果可能如下:"\U00e5\U00a5\U00bd\U00e8\U00ae\U00a4" 在网上查到的解决方法是 ...
- 我的QT5学习之路(目录)
说明:本目录内容为自己学习的心得和记录,参考资料来源于网络,学习过程中多方汲取,如有错误,欢迎指正和批评. Qt开发相关文章目录 一.我的Qt学习之路系列 1.[笔记]我的Qt学习之路(一)——浅谈Q ...
- 我的VSTO之路(二):VSTO程序基本知识
原文:我的VSTO之路(二):VSTO程序基本知识 开始之前,首先我介绍一下我的开发环境:VS2010 + Office 2010,是基于.Net framework 4.0和VSTO 4.0.以下的 ...
- 我的QT5学习之路(一)——浅谈QT的安装和配置
一.前言 说到Qt,不能不说到C++,这门伟大的语言.因为其面向对象的编程思想和陡峭的学习曲线,一开始学习起来很是吃力.Qt从QT4开始基本封装了很多C++的工具库和界面库,而且支持跨平台,这是它最大 ...
- Python学习之路【第一篇】-Python简介和基础入门
1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是 ...
- Redis——学习之路二(初识redis服务器命令)
上一章我们已经知道了如果启动redis服务器,现在我们来学习一下,以及如何用客户端连接服务器.接下来我们来学习一下查看操作服务器的命令. 服务器命令: 1.info——当前redis服务器信息 s ...
- 我的QT5学习之路(三)——模板库、工具类和控件(下)
一.前言 作为第三篇的最后一部分,我们来看一下Qt的控件,谈到控件,就会让人想到界面的美观性和易操作性,进而想到开发的便捷性.作为windows界面开发的MFC曾经是盛行了多少年,但是其弊端也随着其他 ...
- Python学习之路二
今天主要学习了列表,python的列表真的事太强大了,由于内容比较多,今天就先简单的介绍一下新学的几个成员函数吧. 首先我们要了解list是一种序列类型,其构造方式有四种形式: (1)空列表 [] ( ...
- zigbee学习之路(二)点亮LED
一.前言 今天,我来教大家如何点亮led,这也是学习开发板最基础的步骤了. 二.原理分析 cc2530芯片跟虽然是51的内核,但是它跟51单片机还是有区别的,51单片机不需要对IO口进行配置,而cc2 ...
随机推荐
- tensorboard实现tensorflow可视化
1.工程目录 2.data.input_data.py的导入 在tensorflow更新之后可以进行直接的input_data的导入 # from tensorflow.examples.tutori ...
- cf1060C. Maximum Subrectangle(思维 枚举)
题意 题目链接 Sol 好好读题 => 送分题 不好好读题 => 送命题 开始想了\(30\)min数据结构发现根本不会做,重新读了一遍题发现是个傻逼题... \(C_{i, j} = a ...
- cookie和session 区别
cookie机制采用的是在客户端保持状态的方案,session机制采用的是在服务器端保持状态的方案. 1.cookie数据存放在客户的浏览器上,session数据放在服务器上. 2.cookie不是很 ...
- GDAL线面互转换
最近因为项目需要,需做GDAL线面互转的功能,查阅部分资料完成,下面把核心部分的代码贴出来,留个记录,也欢迎大家提问题指正完善. /* * @brief ConvertPolygonToPolylin ...
- Linux 的su 与sudo 的区别,查看所有用户
首先,我们要知道系统当中存在哪些用户. 1.用户名和密码的存储位置 存储帐号的文件:/etc/passwd 存储密码的文件:/etc/shadow 通过/etc/shadow获取的只是密码加密后的Ha ...
- 四元数(Quaternion)和旋转 +欧拉角
四元数介绍 旋转,应该是三种坐标变换--缩放.旋转和平移,中最复杂的一种了.大家应该都听过,有一种旋转的表示方法叫四元数.按照我们的习惯,我们更加熟悉的是另外两种旋转的表示方法--矩阵旋转和欧拉旋转. ...
- 文本(TextView)
今天给大家介绍一下简单的文本. 首先我们看下TextView的继承关系和一些基本的属性: xml文件如下: <?xml version="1.0" encoding=&quo ...
- Java基础之StringBuffer和StringBuilder的区别
StringBuffer是一个字符串的缓存类,属于一个容器,对于容器,我们可以进行增删改查. StringBuffer的容器长度是可变的,并且里面可以存放多种的数据类型.它跟其他容器,比如数组,是很不 ...
- 2.java相对路径与绝对路径
1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如:C:xyz/test.txt 代表了test.txt文件的绝对路径.http://www. ...
- vue从安装到初始化项目