一、前言

  “工欲善其事,必先利其器”,上一节,我介绍了Qt的安装和配置方法,搭建了基本的开发平台。这一节,来通过一个简单的例子来了解Qt的编程样式和规范,开始喽~~~

二、第一个程序——Hello World

  首先,我们可以按照上一节的方法建立一个新的工程,工程的名字可以就叫做Hello,随你的便。在创建工程的过程中,有一个选择是否创建视图界面的选项,这个可以先不选择,因为我们现在只是了解Qt的机制,不需要Qt帮我们做太多的事情,创建完成后,打开main.cpp。

  我做的工作主要就是:

1、屏蔽掉程序自己的对话框程序代码;

2、添加一个label控件,并给他传一个文本值,最后显示。

最后的显示结果:

    其次,我们来分析一下Qt的基本流程。1~3行是头文件包含,这里有两种头文件,第一种是自定义头文件或者本地头文件,用“ ”来进行表示和包含;第二种是系统头文件,这里就是Qt自带的头文件,直接用<>进行表示和包含就可以。第7行是创建一个QApplication的实例,对于 Qt 程序来说,main()函数一般以创建 application 对象(GUI 程序是QApplication,非 GUI 程序是QCoreApplicationQApplication实际上是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继承自QWidgetQWidget则是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学习之路(二)——第一个程序的更多相关文章

  1. IOS学习之路二十(程序json转换数据的中文字符问题解决)

    ios请求web中的json数据的时候经常出现乱码问题: 例如请求结果可能如下:"\U00e5\U00a5\U00bd\U00e8\U00ae\U00a4" 在网上查到的解决方法是 ...

  2. 我的QT5学习之路(目录)

    说明:本目录内容为自己学习的心得和记录,参考资料来源于网络,学习过程中多方汲取,如有错误,欢迎指正和批评. Qt开发相关文章目录 一.我的Qt学习之路系列 1.[笔记]我的Qt学习之路(一)——浅谈Q ...

  3. 我的VSTO之路(二):VSTO程序基本知识

    原文:我的VSTO之路(二):VSTO程序基本知识 开始之前,首先我介绍一下我的开发环境:VS2010 + Office 2010,是基于.Net framework 4.0和VSTO 4.0.以下的 ...

  4. 我的QT5学习之路(一)——浅谈QT的安装和配置

    一.前言 说到Qt,不能不说到C++,这门伟大的语言.因为其面向对象的编程思想和陡峭的学习曲线,一开始学习起来很是吃力.Qt从QT4开始基本封装了很多C++的工具库和界面库,而且支持跨平台,这是它最大 ...

  5. Python学习之路【第一篇】-Python简介和基础入门

    1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是 ...

  6. Redis——学习之路二(初识redis服务器命令)

    上一章我们已经知道了如果启动redis服务器,现在我们来学习一下,以及如何用客户端连接服务器.接下来我们来学习一下查看操作服务器的命令. 服务器命令: 1.info——当前redis服务器信息   s ...

  7. 我的QT5学习之路(三)——模板库、工具类和控件(下)

    一.前言 作为第三篇的最后一部分,我们来看一下Qt的控件,谈到控件,就会让人想到界面的美观性和易操作性,进而想到开发的便捷性.作为windows界面开发的MFC曾经是盛行了多少年,但是其弊端也随着其他 ...

  8. Python学习之路二

    今天主要学习了列表,python的列表真的事太强大了,由于内容比较多,今天就先简单的介绍一下新学的几个成员函数吧. 首先我们要了解list是一种序列类型,其构造方式有四种形式: (1)空列表 [] ( ...

  9. zigbee学习之路(二)点亮LED

    一.前言 今天,我来教大家如何点亮led,这也是学习开发板最基础的步骤了. 二.原理分析 cc2530芯片跟虽然是51的内核,但是它跟51单片机还是有区别的,51单片机不需要对IO口进行配置,而cc2 ...

随机推荐

  1. PAT 1029. Median

    尼玛,数组偶数个数的时候取中位数是取中间两者中的前者,还tmd一直再算平均,卧槽 #include <iostream> #include <cstdio> #include ...

  2. web 开发人员必须学习的 3 门语言

    web 开发人员必须学习的 3 门语言:html  css  js HTML 定义了网页的内容 CSS 描述了网页的布局 JavaScript 网页的行为

  3. JS实现省市联动效果

    实现的效果为:当选择一个省的时候,会自动出现该省下的市级 效果图如下: <body> <div> <!--界面展示--> <span>省份:</s ...

  4. 一行代码解决各种IE的兼容问题

    一行代码解决各种IE的兼容问题  在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 < ...

  5. 自定义View和ViewGroup(有这一篇就够了)

    为了扫除学习中的盲点,尽可能多的覆盖Android知识的边边角角,决定对自定义View做一个稍微全面一点的使用方法总结,在内容上面并没有什么独特的地方,其他大神们的博客上面基本上都有讲这方面的内容,如 ...

  6. Python startswith()函数 与 endswith函数

    函数:startswith() 作用:判断字符串是否以指定字符或子字符串开头一.函数说明语法:string.startswith(str, beg=0,end=len(string))       或 ...

  7. 详解COM Add In的LoadBehavior及其妙用

     Office的所有COM Add In,包括用Shared Add In模板和VSTO Add In模板创建的,都会在注册表里面存储一些信息. 对于当前用户安装的Add In,以Excel为例,对应 ...

  8. exchange 普通用户可以创建通讯组

    运维发现,通讯组多了好多未知名称的,经查为普通用户通过owa新建的,怎么阻止用户新建通讯组呢. 在搭建exchange后,系统会自动创建一个“Default Role Assignment Polic ...

  9. 内置的HTTP服务器【Modern PHP】

    目录 启动服务器 配置服务器 路由器脚本 判断是否为内置的服务器 PHP5.4.0起,PHP内置了Web服务器.对本地开发是个极好的工具,便捷,无需安装WAMP.XAMP或大新那个web服务器,就能在 ...

  10. docker 17.09.0-ce 启动更换网络地址

    一.环境准备 环境1 台虚拟机,系统为centos7 二.17.09.0-ce 安装 卸载安装的所有Docker组件 在 Docker17.03.0-ce 版本中,与在 Docker 1.12 中引入 ...