我的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 ...
随机推荐
- Code Signal_练习题_Are Similar?
Two arrays are called similar if one can be obtained from another by swapping at most one pair of el ...
- 线程与全局解释器锁(GIL)
一.线程概论 1.何为线程 每个进程有一个地址空间,而且默认就有一个控制线程.如果把一个进程比喻为一个车间的工作过程那么线程就是车间里的一个一个流水线. 进程只是用来把资源集中到一起(进程只是一个资源 ...
- android中利用HttpURLConnection进行Get、Post和Session读取页面。
直接上代码,调用的时候要放在线程中. package slj.getsms; import java.io.BufferedReader; import java.io.InputStreamRead ...
- UOJ#347. 【WC2018】通道(边分治)
传送门 就是求两个点 \(a,b\) 使得 \(dis_1(a,b)+dis_2(a,b)+dis_3(a,b)\) 最大 step1 对第一棵树边分治 那么变成 \(d_1(a)+d_1(b)+di ...
- CF954I Yet Another String Matching Problem
传送门 每次操作可以把两个字符串中所有同一种字符变成另外一种 定义两个长度相等的字符串之间的距离为:使两个字符串相等所需要操作的次数的最小值 求 \(s\) 中每一个长度为 \(|t|\) 的连续子串 ...
- 当react 项目使用px2rem
参考资料:http://easywork.xin/2018/09/02/react-2/ 我拿到的设计图 是 375px //配置px2rem px2rem({remUnit: 37.5}) 在 ...
- layui-open-上传文件
<!--选择文件上传--> <script id="upload_file_dialog" type="text/html"> < ...
- Recursive functions and algorithms
http://en.wikipedia.org/wiki/Recursion_(computer_science)#Recursive_functions_and_algorithms A commo ...
- centos 卸载python和yum之后的解决办法
网上看到有同学yum不能使用的消息,出现了下面的结果 无赖的使用了网上的很多方法,还是不行. 于是我卸载了python和yum,觉得自己重新安装python和yum. 步骤1:卸载python rpm ...
- 将eChart图片利用POI导出到Excel
在使用POI进行将数据导出到Excel时, 若要将eChart在前端生成的统计图(如柱状图.折线图.饼图等)一并导出,使用POI在后台构建数据图比较复杂,因此我选择将eChart在前端的统计图的bas ...