首页 Qt 学习之路 2 Qt 学习之路 2(3):Hello, world!

Qt 学习之路 2(3):Hello, world!

122 11.4K

想要学习 Qt 开发,首先要搭建 Qt 开发环境。好在现在搭建 Qt 开发环境还是比较简单的。我们可以到 Qt 官方网站找到最新版本的 Qt。在 Downloads 页面,可以看到有几个版本的 Qt:Qt SDK、Qt Library、Qt Creator 等等。它们分别是:

  • Qt SDK:包含了 Qt 库以及 Qt 的开发工具(IDE、i18n 等工具),是一套完整的开发环境。当然,这个的体积也是最大的(Windows 平台大约 1.7G,其它平台大约 780M)。如果仅仅为开发 Qt,建议选择这一项下载安装。安装方法很简单,同普通程序没有什么区别。所需注意的是,安装过程中可能能够提供选择是否安装源代码,是否安装 mingw 编译器(Windows),这个就按照需要进行选择即可。另外值得说明的是,Qt SDK 通常比单独的 Qt 库版本要旧一些。比如现在 Qt 正式版是 4.8.2,但是 Qt SDK 的最新版 1.2.1 中包含的 Qt 是 4.8.1。
  • Qt Library:仅包含 Qt 库。如果您已经安装了 Qt 开发环境,为了升级一下 SDK 中提供的 Qt 库版本,就可以安装这一个。安装过之后,应该需要在 IDE 中配置安装路径,以便找到最新版本的 Qt(如果不是覆盖安装的话)。
  • Qt Creator:基于 Qt 构建的一个轻量级 IDE,现在最新版是 2.5.2,还是比较好用的,建议使用 Qt Creator 进行开发。当然,如果你已经习惯了 VS2010 这样的工具,可以在页面最下方找到相应的 Addin。很多朋友希望阅读 Qt 代码以提高自己的开发水平。当然,Qt 的经典代码是 KDE,不过这个项目不大适合初学者阅读。此时,我们就可以选择阅读 Qt Creator 的代码,它的代码还是比较清晰的。

当我们安装完成 Qt 开发环境之后,就可以使用 Qt Creator 进行开发。在本系列中,豆子会一直使用这个 IDE 进行讲解。至于编译器,豆子一般会使用 mingw 或者 gcc。为了编译 Qt 5 的程序,你应该使用 gcc 4.5 以上的版本,这意味着,如果你是使用 Qt SDK 自带的 mingw,是不能编译 Qt 5 的程序的(因为这个自带的版本是 4.4),你应该升级 mingw 为 4.5 以上版本。

至此,我们已经有了 Qt 4 的完整开发环境。如果你想要开发 Qt 5,由于现在(2012 年 8 月) Qt 5 还处于测试阶段,并没有提供二进制库,所以我们需要使用 git 自己获取 Qt 5 的源代码自己编译(一般需要几个小时时间)。豆子非常不建议在 Windows 上编译 Qt 5,因为可能会出很多问题。如果你想尝试,可以参考这里。豆子提一句,在 Windows 上编译 Qt 5,需要安装 perl(并且要安装 GetOpt::Long 模块)、python 和 git,并且需要找到彼此路径。相比而言,Linux 上面就会简单很多。豆子建议,如果你想在 Windows 上尝试 Qt 5,可以考虑安装一个虚拟机,使用 Linux 平台;或者自己试着直接在 Windows 本地编译。豆子的环境是使用 openSUSE。openSUSE 的 Qt 5.0 Development Snapshots 已经提供了 Qt 5 二进制版本,免去了编译的过程。基于此,本文的 Qt 4 版本将在 Windows 平台上使用 mingw 进行测试;Qt 5 版本将在 openSUSE 上使用 gcc 4.6 进行测试。在未来官方推出 Qt 5 Windows 平台的二进制版本,也不排除在 Windows 上面测试 Qt 5 代码。

在 Qt Creator 中,我们可以在菜单栏的工具-选项-构建和运行的“Qt 版本”和“工具链”这两个选项卡中配置 Qt Creator 所使用的 Qt 版本和编译器。这或许是最重要的步骤,包括添加新的 Qt 版本以及以后的切换编译器或者 Qt 升级等。

下面尝试开发第一个 Qt 项目:HelloWorld。在 Qt Creator 中新建一个工程:

Qt Creator 新建工程

点击这个“新建文件或工程”,在左侧选择项目-Applications,中间选择 Qt Gui 应用,然后点击“选择...”:

Qt Creator GUI 工程

在弹出的对话框中填写名称、创建路径等信息:

Qt Creator 工程名字及位置

点击“下一步”,选择该工程的编译器。这里我们只选择 mingw 调试即可(在以后的项目中,根据自己的需要选择。)Shadow Build 的含义是“影子构建”,即将构建生成的文件不放在源代码文件夹下。这样可以最大地保持源代码文件夹的整洁。

Qt Creator 编译器选择

点击“下一步”,可以选择生成的主窗口文件。不过在我们的简单示例中是不需要这么复杂的窗口的,因此我们尽可能简单地选择,将“创建界面”的选择去除:

Qt Creator MainWindow

终于到了最后一步。这里是在询问我们是否添加版本控制。对于我们的小项目当然是不需要的,所以选择“无”,然后点击“完成”即可:

Qt Creator 版本管理

可以看到,Qt Creator 帮助我们在 HelloWorld 项目文件夹下生成了四个文件:main.cpp,mainwindow.cpp,mainwindow.h 和 HelloWorld.pro。pro 文件就是 Qt 工程文件(project file),由 qmake 处理,生成 make 程序所需要的 makefile;main.cpp 里面就是一个main函数,作为应用程序的入口函数;其他两个文件就是先前我们曾经指定的文件名的文件。

我们将 main.cpp 修改如下:

#include <QApplication>
#include <QLabel>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QLabel label("Hello, world");
    label.show();

    return app.exec();
}

点击 Qt Creater 左侧下面的绿色三角按钮即可运行(这里一共有三个按钮,从上到下分别是“运行”、“调试”和“构建”)。如果没有错误的话,就会看到运行结果:

Qt HelloWorld 程序运行结果

这个程序有这么几行。我们解释一下。

前两行是 C++ 的 include 语句,这里我们引入的是QApplication以及QLabel这两个类。main()函数中第一句是创建一个QApplication类的实例。对于 Qt 程序来说,main()函数一般以创建 application 对象(GUI 程序是QApplication,非 GUI 程序是QCoreApplicationQApplication实际上是QCoreApplication的子类。)开始,后面才是实际业务的代码。这个对象用于管理 Qt 程序的生命周期,开启事件循环,这一切都是必不可少的。在我们创建了QApplication对象之后,直接创建一个QLabel对象,构造函数赋值“Hello, world”,当然就是能够在QLabel上面显示这行文本。最后调用QLabelshow()函数将其显示出来。main()函数最后,调用app.exec(),开启事件循环。我们现在可以简单地将事件循环理解成一段无限循环。正因为如此,我们在栈上构建了QLabel对象,却能够一直显示在那里(试想,如果不是无限循环,main()函数立刻会退出,QLabel对象当然也就直接析构了)。

示例程序我们已经讲解完毕。下面再说一点。我们可以将上面的程序改写成下面的代码吗?

#include <QApplication>
#include <QLabel>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QLabel *label = new QLabel("Hello, world");
    label->show();

    return app.exec();
}

答案是,可以建议这样做!

首先,按照标准 C++ 来看这段程序。这里存在着内存泄露。当exec()退出时(也就是事件循环结束的时候。窗口关闭,事件循环就会结束),label 是没办法 delete 的。这就造成了内存泄露。当然,由于程序结束,操作系统会负责回收内存,所以这个问题不会很严重。即便你这样修改了代码再运行,也不会有任何错误。

早期版本的 Qt 可能会有问题(详见本文最后带有删除线的部分,不过豆子也没有测试,只是看到有文章这样介绍),不过在新版本的 Qt 基本不存在问题。在新版本的 Qt 中,app.exec()的实现机制确定,当最后一个可视组件关闭之后,主事件循环(也就是app.exec())才会退出,main()函数结束(此时会销毁app)。这意味着,所有可视元素已经都关闭了,也就不存在后文提到的,QPaintDevice没有QApplication实例这种情况。另外,如果你是显式关闭了QApplication实例,例如调用了qApp->quit()之类的函数,QApplication的最后一个动作将会是关闭所有窗口。所以,即便在这种情况下,也不会出现类这种问题。由于是在main()函数中,当main()函数结束时,操作系统会回收进程所占用的资源,相当于没有内存泄露。不过,这里有一个潜在的问题:操作系统只会粗暴地释放掉所占内存,并不会调用对象的析构函数(这与调用delete运算符是不同的),所以,很有可能有些资源占用不会被“正确”释放。事实上,在最新版的 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();
}

这段代码不仅在堆上创建组件实例,更是把QApplication本身创建在了堆上。不过,注意,它使用了智能指针,因此我们不需要考虑操作系统直接释放内存导致的资源占用的问题。

当然,允许使用并不一定意味着我们建议这样使用。毕竟,这是种不好的用法(就像我们不推荐利用异常控制业务逻辑一样),因为存在内存泄露。而且对程序维护者也是不好的。所以,我们还是推荐在栈上创建组件。因为要靠人工管理newdelete的出错概率要远大于在栈上的自动控制。除此之外,在堆上和在栈上创建已经没有任何区别。

如果你必须在堆上创建对象,不妨增加一句:

label->setAttribute(Qt::WA_DeleteOnClose);

这点提示足够告诉程序维护者,你已经考虑到内存问题了。

严重的是,label 是建立在堆上的,app 是建立在栈上的。这意味着,label 会在 app 之后析构。也就是说,label 的生命周期长于 app 的生命周期。这可是 Qt 编程的大忌。因为在 Qt 中,所有的QPaintDevice必须要在有QApplication实例的情况下创建和使用。大家好奇的话,可以提一句,QLabel继承自QWidgetQWidget则是QPaintDevice的子类。之所以上面的代码不会有问题,是因为 app 退出时,label 已经关闭,这样的话,label 的所有QPaintDevice一般都不会被访问到了。但是,如果我们的程序,在 app 退出时,组件却没有关闭,这就会造成程序崩溃。(如果你想知道,怎样做才能让 app 退出时,组件却不退出,那么豆子可以告诉你,当你的程序在打开了一个网页的下拉框时关闭窗口,你的程序就会崩溃了!)

122 评论

nihao 2012年8月23日 - 10:43

赞!望博主继续写出浅显易懂的文章!

回复
Anonymous 2012年8月23日 - 22:19

qt5不是优选原生编译器了么,相比gcc,linux是没话说,主要是mingw,win7和win8(猜测)都会是msvc主导吧,mac也应该会更倾向于调用xcode而非gnu(是这个么还是xcode只是editor,没有mac并不知道)。似乎linuxgcc,winmsvc和macxcode已经是既定方针了。不管怎么说,使用该平台的官方编译器,更优雅一点吧。

回复
DevBean 2012年8月24日 - 07:58

是的,的确是这个样子。新版本的 Qt Creator 都已经推荐使用自动更新版本的 mingw,而不是自带的。在未来的版本中,Qt Creator 也会逐步停止自带编译器。我在这里主要是没有安装 MSVC 编译器,所以直接使用的 mingw ;-p

回复
大米 2012年9月1日 - 21:37

再请教几个问题。。 Qt Creator的源码在哪里能下载。还有您说的mingw4.5以上版本。这两个东西我都没在官网的download看到。4.5版本的用在QT4上是否有不妥?十分感谢

回复
DevBean 2012年9月2日 - 07:33

Qt Creator 的源代码是在 http://qt.gitorious.org/qt-creator,可以使用 git clone 其代码库。mingw 4.5 需要在 mingw 官网找到其下载地址。Qt 4 不需要 mingw 4.5 以上版本;事实上,Qt 4 就是使用 mingw 4.4 编译的。顺便说一句,mingw 最新版应该是 4.7 了。

回复
大米 2012年9月2日 - 19:25

谢谢BEAN兄的热心指教。谢谢

回复
anonymous 2012年9月24日 - 08:22

好奇怪,为什么文章里的图片都显示一片空白呢?但是点击倒是能把图片正常放大显示。

回复
anonymous 2012年9月24日 - 08:24

呃,这下更奇怪了,在我留言之后所有图片都显示正常了。但换个新浏览器打开还是空白,囧……

回复
DevBean 2012年9月24日 - 09:11

原本我也遇到了这个问题,以为是我这里的网速不够。现在发现看来大家都有这个问题…可能是 wordpress 一个插件的问题,现在已经修改过了,请刷新试试~谢谢~

回复
anonymous 2012年9月24日 - 10:28

嗯,这下可以正常显示了,博主效率好高,赞! 😀

回复
DevBean 2012年9月24日 - 17:08

过奖过奖~呵呵

Michael_BJFU 2012年10月2日 - 21:42

豆子先生,如果使用QtCreator,应该如何检测内存泄漏状况?visual leak detector?

回复
DevBean 2012年10月2日 - 22:22

Qt Creator 自己没有提供内存泄露工具,使用第三方的吧。另外需要注意的是,很多第三方工具库对 Qt 支持不是很好,因为 Qt 使用自己的对象树在一定程度上会自己管理内存,很多 new 不需要 delete,因此有些工具会当成内存泄露,实际是没有的。

回复
great 2012年10月12日 - 20:29

嗯,我不得不说,我在windows8上Mingw和MSVC编译了Qt5,至于你说的Python,自认为只编译QtBase模块完全够用,lupdate、lupdate虽然不在qtbase模块中,但是我用的Qt4的工具,生成的qm文件可以在Qt5程序中完美加载;Perl这个是必须的;最后不要用git,慢的要死(崩溃不会断点,气死我了),还不如下载Qt5Beta的7z压缩包呢

回复
DevBean 2012年10月13日 - 08:59

qm 文件没有修改,所以 Qt4 的完全足够。用 git 的话,只是为了能够随时获取最新版本的代码,第一次会很慢,之后会好一些。如果不追求最新版代码,直接下载压缩包会更快一些。

回复
great 2013年1月19日 - 12:09

最近在Linux上编译了Qt5,太不成功了。编译了3、4遍,编译成功了,但程序各种不对。想起了那次在这里看的那句话,是不是说反了,Windows上编译一遍保准成功,Linux不是这里出问题就是那里出问题。

回复
豆子 2013年1月21日 - 10:10

那倒是有可能。不过 README 文件中已经给出了详细的编译步骤,个人觉得如果版本一致的话,应该比较方便。不过我还是直接使用预编译的版本比较多 ;-P

回复
langziyang 2012年11月23日 - 13:50

那么在第二种写法上,除了改为第一种写法,还有没有解决方法呢

回复
DevBean 2012年11月23日 - 14:01

单纯为了解决内存泄露,你可以选择添加一句:label->setAttribute(Qt::WA_DeleteOnClose); 但是这样依然解决不了 QPaintDevice 的问题。所以建议是,不要这么写!

回复
BobYang 2012年11月24日 - 19:47

请教博主,在构建与运行中配置QT版本是:QT4.8.3,编译器是:MinGW;直接运行HelloWorld项目中的代码时,系统提示HeelloWorld.exe已停止工作,不能显示窗口。我是新手,烦请多指教。

回复
BobYang 2012年11月24日 - 19:57

我构建编译输出窗口信息如下:
19:56:28: Running steps for project HelloWorld...
19:56:28: 配置没有改变, 跳过 qmake 步骤.
19:56:28: 正在启动 "C:\MinGW\bin\mingw32-make.exe"
{1"?} {2?}
C:/MinGW/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'G:/Qt_Project/QtLearn/HelloWorld-build-Desktop-Debug'
mingw32-make[1]: Nothing to be done for 'first'.
mingw32-make[1]: Leaving directory 'G:/Qt_Project/QtLearn/HelloWorld-build-Desktop-Debug'
19:56:29: 进程"C:\MinGW\bin\mingw32-make.exe"正常退出。

回复
DevBean 2012年11月25日 - 10:12

编译是没有问题的,你的程序应该有错误,运行时错误一般是指针、内存问题,仔细检查看程序看看哦

回复
BobYang 2012年11月25日 - 11:33

博主,我新建个QTGui工程,默认的Main.cpp函数,没修改任何代码,还是运行错误。

回复
BobYang 2012年11月25日 - 11:33

是不是我安装配置出问题了?

回复
DevBean 2012年11月25日 - 15:36

有可能配置问题,但是即便如此,也不应该出现运行时错误啊。

回复
zhupp 2013年1月6日 - 16:32

看了版本1的Qt学习之路,很不错!看到一半又偶尔找到2,呵呵,作者继续加油!

回复
豆子 2013年1月6日 - 18:53

多谢支持!

回复
hwb 2013年1月13日 - 13:56

博主,你好,我对你说的这句话表示不理解,可以在讲的详细点吗? 当你的程序在打开了一个网页的下拉框时关闭窗口,你的程序就会崩溃了!

回复
豆子 2013年1月14日 - 09:12

这只是举一个例子。其情景是这样的:制作一个网页,里面有一个下拉框。然后你点击下拉框将其打开,显示下拉框的各个选项之后,在不关闭下拉框的情况下直接关闭窗口,此时程序崩溃。

回复
hwb 2013年1月14日 - 11:59

嗯,知道了.thanks

回复
andmoe 2013年1月15日 - 15:28

Qt5正式版只有VS2010版,windows下必须完整安装vs2010才能用吗?

回复
豆子 2013年1月16日 - 09:48

目前只有 VS2010 版和各种 Linux 版。1 月底可能会有 mingw 版。Windows 下推荐使用除 Express 版以外 VS2010,这样比较方便。如果要使用 Express 版的 VS,官方说明要再安装 WinSDK 才行,具体没有尝试过。

回复
why_not 2013年1月31日 - 18:17

你好博主,我想请教你一个问题。我是用的qt4.8.4+qt creator+mingw。然后我编写了一个hello world,debug模式报了很多错,后来发现是在make这一步出的错,release模式编译通过,但是运行会出现已停止工作的问题。这是怎么回事啊?

回复
豆子 2013年2月5日 - 15:11

这个只能看具体错误,可能是环境配置问题之类,由于信息太少,也说不清楚怎样解决。

回复
realfan 2013年2月7日 - 09:37

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel *label = new QLabel("Hello, world");
label->show();
return app.exec();
}
好像也没问题。看了一下帮助文档,
Warning: Qt requires that a QGuiApplication object exists before any paint devices can be created. Paint devices access window system resources, and these resources are not initialized before an application object is created.
PaintDevice创建时,必须已经存在QGuiApplication对象,因为PaintDevice要访问系统资源,这些资源需要application对象初始化。是不是如果已经有过application,就是已经初始化过了,即使app不在了,也没关系了呢。《C++ CUI Qt4》第一章的的例子就是
QLabel *label = new QLabel("Hello Qt");
label->show();
这样写的。我试了,运行,也没出错。希望博主帮忙解惑,谢谢!

回复
豆子 2013年2月7日 - 09:53

文档中说的是要求“exists”,因此应该理解成这个 QApplication 对象必须“存在”,而不是“存在过”。的确,《C++ GUI Qt4》这本书的第一个例子也是直接在堆上创建的,严格来说这个例子是值得商榷的。对于简单的例子,这样的写法的确没有任何问题,但是有隐藏的错误,而这种错误可能会是很难注意到的。就像你在 delete 一个指针之后立即使用,一般也不会造成程序崩溃。这里也是类似的情形。

回复
realfan 2013年2月7日 - 11:06

有道理,赞同你的观点。Qt文档应该写得再清楚一些,或者强调一下。

回复
xiaohui_hubei 2014年1月10日 - 20:04

会不会是Qt自动检测并释放,有没有人试验过,或是看过源代码?

回复
Kiwee 2013年4月15日 - 18:13

楼主。。。你的学习之路1里面前面的代码好像都用的这种指针创建对象的吧。。。。我刚刚开始学QT。。。用的QT5。。多谢出了这个系列的文章

回复
豆子 2013年4月16日 - 08:58

是的,这是因为之前是按照《C++ GUI Programming with Qt4, 2nd Edition》中的代码来写的。但是这不是 Qt 的最佳实践,原因我们在后续已经说明。所以这里我们换成了 Qt 推荐的写法,这种写法更加合理。

回复
nighcate 2015年1月16日 - 10:59

楼主你好,你说第二种方法不是Qt推荐的方法,但是我用QtDesigner设计后,在vs2013中使用,似乎就是用了这种方法,所以有点混乱了。不好意思我是新手。

回复
豆子 2015年1月17日 - 12:32

所谓“不推荐”,并不是不能这么写,只是按照某些“完美主义者”的观点来看,可能会有问题(不过考虑到操作系统对垃圾资源的回收,实际上基本不会有这个问题)。“不建议”只是个人意见,并不代表官方看法。

回复
hailong 2013年5月9日 - 11:24

其实可以用智能指针来避免内存泄露。显式delete总是不爽。

回复
豆子 2013年5月9日 - 15:32

这个就是见仁见智的问题了,有人喜欢显式 delete,就为了节省使用类的那些开销…更多是习惯问题,而不是谁好谁坏了。

回复
信相一号 2013年5月11日 - 17:22

本人是菜鸟,很弱的问豆子一个问题:用Qt编程时,是否可以只使用绘图方式(即用qt designer编程),而不使用手工写代码的形式编程?谢谢!

回复
豆子 2013年5月12日 - 21:28

Qt Designer 是叫“可视化设计”,不是绘图方式。Qt Designer 基本可以替代代码编写,只不过有些稍微复杂些的功能还是得用代码实现。

回复
信相一号 2013年5月13日 - 11:20

谢谢 ,再问一个:现在的安卓手机的系统ui和app一般用什么软件开发? 可以用qt开发吗?

回复
豆子 2013年5月13日 - 12:25

Qt 5.2 可能会推出比较成熟的 for Android 版本,目前仅是测试版。Android 平台的 app 使用的是 Java

回复
杨超 2014年6月8日 - 17:34

你用的qt哪个版本,编译环境是什么,我用的qt5.3,但跟你教程不一样,新手,不知该如何下手

豆子 2014年6月12日 - 10:33

哪里有问题?应该 Qt 5 的都是类似的。

zeroten 2013年6月10日 - 14:11

你好,我只有c的基础,要学Qt,是不是要先回去学c++

回复
豆子 2013年6月14日 - 11:08

要学 Qt,必须要 C++ 基础的哦,所以最好还是先去学 C++ 吧

回复
hilbet 2013年6月15日 - 13:05

请教一下博主,怎么在linux系统下用qtcareator交叉编译windows程序呢,我用的是ubuntu12.04,下了mingw32,用命令行交叉编译windows下简单的C++控制台程序没有问题,但不知道怎么设置可以编译qt程序。

回复
豆子 2013年6月17日 - 09:08

这个具体没有试过,不过大致过程应该是,安装过 mingw32 之后,使用 mingw32 编译 Qt(在此过程中可能还需要安装下 DirectX 的库),然后应该就可以编译了

回复
twyok 2013年6月24日 - 11:20

请教一下博主:
我在最新的redhat系统上安装Qt5,gcc版本4.8.1,做了简单的测试程序,编译时出现如下错误:

/usr/bin/ld: skipping incompatible /opt/Qt5.1.0/5.1.0-beta1/gcc/lib/libQt5Widgets.so when searching for -lQt5Widgets
/usr/bin/ld: cannot find -lQt5Widgets

collect2: error: ld returned 1 exit status

make: *** [tes1] Error 1

11:10:26: 进程"/usr/bin/make"退出,退出代码 2 。

Error while building/deploying project tes1 (kit: Desktop Qt 5.1.0 GCC 32bit)
当执行步骤 'Make'时

回复
豆子 2013年6月24日 - 12:12

看错误信息是因为版本不兼容,你在安装的时候是不是把 5.1 beta 和 5.0 混用了?

回复
twyok 2013年6月24日 - 13:52

好像是不兼容,但我重新安装系统,只安装qt5.1, 还是出现其问题

回复
豆子 2013年6月25日 - 09:02

我记得有些版本的 Linux 源里面 Qt 各个模块是分开下载的,所以在下载的时候注意看一下各个模块的版本。不过,还是推荐从官网直接下载安装包进行安装,在初期学习时会省掉很多麻烦。

回复
twyok 2013年6月25日 - 10:19

嗯,现在我把它安装在32位系统上没问题了,不知道,是否根系统32或64有关,或安装时相应的32位依赖库没有吧

回复
ustckun 2013年7月22日 - 15:07

你好,我使用的是Qt5.1,如何在5.1的版本中添加mingw编译器?下载时下载的就是64位的windows版本(VS2012),现在的Qt也没有SDK包了…

回复
豆子 2013年7月22日 - 17:43

现在 5.1 只提供了 32 位 mingw 安装包,没有 64 位的,所以你只能下载这个(你下载的 64 位 VS2012 安装包是不能用 mingw 编译的)。你所说的添加 mingw 编译器应该是在 Qt Creator 中添加吧?在 Qt Creator 中的 Option - Build & Run 里面是有的。

回复
ustckun 2013年7月22日 - 18:11

Build&Run里我看了,调试器里我自动检测不到,编译器里没有mingw,手动添加一个mingw要求我给一个路径……好纠结~

回复
张子帅 2014年4月20日 - 09:08

我用的是Ubuntu14.04 64位,qt:5.2
看了一下系统自带的编译器为gcc 4.8
qt找不到系统的编译器gcc,
手动添加指定系统gcc时具体路径是哪啊

回复
豆子 2014年4月21日 - 11:07

在 Qt Creator 的选项的 Kit 里面可以设置编译器路径。

回复
rewriter 2013年11月19日 - 18:50

楼主写的好棒!真心帮大忙了!

回复
豆子 2013年11月19日 - 22:43

过奖过奖

回复
LSH 2013年12月2日 - 21:26

谢谢博主的文章
文中说:label生命周期长于application会出问题,那么如果消息循环结束了,在销毁application之前删除label的引用这样可以么,像如下代码。这个生命周期的比较是根据application对象的生命周期还是消息循环的生命周期?

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
int result;

QLabel *label = new QLabel("Hello World");
label->show();

result = a.exec();
delete(label);
return result;
}

回复
豆子 2013年12月2日 - 21:57

理论上是可以的,不过我也没有测试过,重现这种问题也不容易

回复
worldsing 2013年12月31日 - 22:38

本人对C+++不太熟啊(搞硬件的),Helloword进程结束时OS会销毁进程的所有资源吧?
当然,写程序来说不提倡,如果进程没有推出,多处new而没有delete会让进程变成肿瘤,
这个肿瘤会随着进程死去而消失,豆子,小的我理解的对么?

回复
豆子 2014年1月3日 - 11:42

这完全依赖于操作系统的实现。不过,现在所有的操作系统都是将进程的堆(也就是 new 和 delete 作用的区域)分配到进程的私有地址空间,所以当进程结束时,这些内存区域会被释放掉。不过,对于共享内存区,由于是共享的,所以不会被释放。

回复
xiaohui_hubei 2014年1月10日 - 20:02

第二种写法程序没有崩溃啊。
#include
#include

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// QLabel label("hello world!");
// label.show();
QLabel *label = new QLabel("hello world!");
label->show();
return app.exec();
}

回复
豆子 2014年1月11日 - 21:22

有了一些修改,现在的 Qt 版本应该是允许这样做了。

回复
Jimmy 2014年2月18日 - 10:34

超棒的教程!看了一半前一个版本,搜问题时找到第二版的。发现博主都还一直在更新。点赞,学生党没钱……只能回复以表谢意~

回复
豆子 2014年2月18日 - 12:34

感谢支持!

回复
robberjohn 2014年3月17日 - 21:23

博主我刚开始看你的书,我用的是64位VS2012,请问现在依然不建议在windows上编译Qt5吗?

回复
豆子 2014年3月18日 - 08:53

“不建议”的意思是,在 Windows 上面编译比较困难,但并不是不能编译。如果官方提供的几个安装包都不能满足你的需要的话,自己编译也无妨的。不过,64位版本的 VS2012 应该默认安装了32位编译器的,仅仅学习的话直接安装32位版本 Qt 也是可以的。

回复
呵呵 2014年4月9日 - 22:46

博主,请问怎么每次新建项目时,都能自动添加 QMAKE += std=c++11 ? 改模板么?能教教怎么做么…………不胜感激

回复
呵呵 2014年4月9日 - 22:48

是QMAKE__CXXFLAGS,抱歉

回复
壹号 2014年4月14日 - 20:59

恕我愚昧,请问饿QT具体有哪些应用呀?另外,您是怎样看待QT for android 的前景的?谢谢啦!!1

回复
豆子 2014年4月15日 - 09:16

很多应用都使用了 Qt。Linux KDE 桌面环境是现在最大的开源项目之一;Google Earth、Photoshop Elements、Skype、新版本的 3ds Max、新版本的 WPS 等都是使用的 Qt。Qt for Android 目前不是非常了解,不便评论。不过个人认为如果性能没有问题的话,对于跨平台应用还是非常有利的,毕竟使用 Qt 编译的话可以很方便的移植到 iOS、WP 等平台,有点类似与 PhoneGap 的概念,只不过无需更多 HTML/JS 的支持。

回复
今朝有酒今朝醉 2014年7月5日 - 11:08

请问为什么我的.cpp文件显示不可执行?

回复
豆子 2014年7月6日 - 09:57

不大清楚什么是“不可执行”?

回复
d 2014年11月23日 - 08:51

如果在主函数结尾,可以不释放;在其他block结尾,new出来的内存是逆序释放的,这是c++标准的规定。所以不存在内存非法访问的问题。

回复
d 2014年11月23日 - 08:53

没说清楚,I mean类(这里的智能指针)的析构顺序

回复
Qter 2014年12月19日 - 15:19

您好,我安装了qt creator3.3;也安装了qt5.4的源代码;想问一下在qt creator里怎么看源代码,比现在点击QApplication打开的是.h文件,怎样打开.cpp文件?

回复
豆子 2014年12月21日 - 21:12

QtCreator 好像没有类似的功能,需要自己由头文件找到源代码文件。

回复
xtbliss158 2015年3月4日 - 20:29

豆子老师你好,我用Qt5.4创建了一个新项目运行的时候出现:This application has requested the Runtime to terminate it in an unusual way.Please contact the application's support team for more information.请指教。

回复
豆子 2015年3月9日 - 14:14

可能是环境问题,这个不大清楚是怎么回事,需要具体分析。

回复
肉松 2015年3月5日 - 00:30

看到作者对每条评论进行了 回复
精神太值得钦佩
膜拜大神!
好好学习!

回复
cssin 2015年4月28日 - 22:18

我的开发环境是MAC OS X 10.10.3 + Qt 5.3.2
按照教程写了个HelloWorld,其他都没问题,但是最大化之后再最小化,程序崩了,这是什么原因?

回复
豆子 2015年6月3日 - 10:03

这个问题还没有遇到过,不知道是什么原因。正常的话是没有问题的。

回复
Bill 2015年7月30日 - 12:57

豆子脑湿太棒了,我支持你~~

回复
Shana 2015年9月20日 - 14:51

我是个新手,在照着上面创建项目,更改代码以后点那个绿色的开始以后出现了错误。

: “14:45:53: 为项目untitled2执行步骤 ...
14:45:53: 正在启动 "C:\Qt\Qt5.4.0\5.4\mingw491_32\bin\qmake.exe" C:\Users\灼眼のシャナ\Desktop\__\Qt\untitled2\untitled2.pro -r -spec win32-g++ "CONFIG+=debug"

Cannot find file: C:\Users\灼眼のシャナ\Desktop\__\Qt\untitled2\untitled2.pro.
14:45:53: 进程"C:\Qt\Qt5.4.0\5.4\mingw491_32\bin\qmake.exe"退出,退出代码 2 。
Error while building/deploying project untitled2 (kit: Desktop Qt 5.4.0 MinGW 32bit)
When executing step "qmake"
14:45:53: Elapsed time: 00:00.”

qt下载的版本是qt-opensource-windows-x86-mingw491_opengl-5.4.0。
这个应该什么都不用设置吧?但是没法运行。

回复
豆子 2015年9月21日 - 14:59

现在 qmake 不支持路径中包含非英文,所以你的路径必须全部使用英文才可以

回复
我是安娜 2016年5月13日 - 01:15

请楼主解释一下这样创建窗口的方式生成的mianwindow.h里面UI和对象ui
我看到你后面讲QAction里面没有用到这个。
初学这认真地飘过。。。
谢谢。

回复
豆子 2016年5月20日 - 15:10

UI是 IDE 自动生成的界面文件,如果用不到的话就不用管它,或者直接删除也可以;这个文件可以用设计师拖放设计界面

回复
iamhuskar 2016年5月23日 - 14:00

app.exec()到底什么时候才会退出呢?
当前的例子是点击label的关闭按钮 就退出。
如果是一个window上的label 我关闭label肯定不会退出。只有在点击window关闭按钮的时候才会退出。这个exec退出的条件是什么

回复
豆子 2016年5月23日 - 21:21

默认点击右上角的关闭按钮就会退出,使用qApp->quit()函数则可以编程退出。

回复
天丝 2016年5月23日 - 19:02

请问,我的qt似乎没有 QT gui 应用这个选项,在相应位置只有QT widgets application
请问这是什么意思?

回复
豆子 2016年5月23日 - 21:22

对于 Qt 5,widgets 是建立在 gui 之上的,所以 gui 会默认添加

回复
天丝 2016年7月8日 - 17:53

谢谢!

回复
Ollog 2016年7月5日 - 15:26

这么多年下来应该造福了不少啃不下文档的人,请问下为什么label释放不了呢?他不是自动变量吗

回复
豆子 2016年7月8日 - 14:26

label 是在堆上面创建的,堆上面创建的变量都要手动释放的

回复
胡马依北风 2016年10月17日 - 14:01

应该可以用 c++ 自带的智能指针,这种智能指针实际上是对象,建立在栈上的,表现的像指针而已。不知道 Qt 的 QScopedPointer 是不是也类似?
std::unique_ptr label(new QLabel("Hello Qt!"));

回复
胡马依北风 2016年10月17日 - 14:09

查了下 QScopedPointer 的说明,是这样的:QScopedPointer is a small utility class that heavily simplifies this by assigning stack-based memory ownership to heap allocations, more generally called resource acquisition is initialization (RAII)

这个应该是和 c++ 的智能指针大同小异,应该不是建立在 heap 上的。就是不知道怎么去测试变量,到底是在栈中还是在堆中,不知博主有好的办法么?

回复
豆子 2016年10月17日 - 22:17

我也不知道是否有这种方法。看起来按照 C++ 的要求,使用 new 创建的都是在堆上,不使用的话就是在栈上;即便是智能指针,也应该符合这一要求。

回复
张仙 2017年3月7日 - 16:06

豆子前辈,我用了示例里的connect函数,但是编译说“重载中没有一个可以转换所有参数类型”,但是我用的应该是qt5,因为没有安装qt4。不知道是不是哪一步设置搞错了。

回复
HandsomePot 2018年9月7日 - 10:37

感谢作者,已经买了你的书,不过还是这里看方便一点。顺便说下微信的打赏码无效了。

回复
豆子 2018年9月8日 - 17:31

我检查了下,微信的二维码好像是正常的

回复
wansst 2020年4月2日 - 17:05

书在哪里有卖 叫什么名字?

回复
豆子 2020年4月21日 - 13:29

现在新版都是 QML 的,基本没有 C++ 的内容。如果你需要学习 QML 可以买,否则就不建议了。书名是《Qt 5编程入门(第2版)》

回复
董奋斗 2019年5月7日 - 14:49

我按照博主的一步一步创建,直接就是报如下错误,请帮忙解惑。谢谢
..\helloworld\main.cpp: In function 'int qMain(int, char**)':
..\helloworld\main.cpp:14:4: error: 'QLabel' was not declared in this scope
QLabel label("Hello, world");
^~~~~~
..\helloworld\main.cpp:14:4: note: suggested alternative: 'QLineF'
QLabel label("Hello, world");
^~~~~~
QLineF
..\helloworld\main.cpp:15:4: error: 'label' was not declared in this scope
label.show();
^~~~~
..\helloworld\main.cpp:15:4: note: suggested alternative: 'labs'
label.show();
^~~~~
labs
mingw32-make[1]: *** [Makefile.Debug:349: debug/main.o] Error 1
mingw32-make[1]: Leaving directory 'D:/07_Program/QT/Helloworld/build-helloworld-Desktop_Qt_5_12_0_MinGW_64_bit-Debug'
mingw32-make: *** [Makefile:36: debug] Error 2
14:44:04: The process "E:\ProgramFiles\QTSOFTWARE\Tools\mingw730_64\bin\mingw32-make.exe" exited with code 2.
Error while building/deploying project helloworld (kit: Desktop Qt 5.12.0 MinGW 64-bit)
The kit Desktop Qt 5.12.0 MinGW 64-bit has configuration issues which might be the root cause for this problem.
When executing step "Make"
14:44:04: Elapsed time: 00:03.

回复
豆子 2019年5月8日 - 15:17

按照错误提示,‘QLabel’ was not declared in this scope,也就是没有找到 QLabel。可能是没有 include

回复
cairne 2020年1月13日 - 16:59

没想到豆子还在回复,真是兢兢业业,佩服,佩服!

回复
Dean 2020年8月16日 - 15:27

豆子大神, 請問您在 Qt 学习之路 2(11):布局管理器的程序(下面) 為什麼還是使用 第二种写法?
请帮忙解惑。谢谢

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QWidget window;
window.setWindowTitle("Enter your age");

QSpinBox *spinBox = new QSpinBox(&window);
QSlider *slider = new QSlider(Qt::Horizontal, &window);
.......
window.show();

return app.exec();
}

回复
豆子 2020年8月16日 - 22:54

这个写法应该没有问题,根窗口是在栈上创建的,内部组件都是使用根窗口作为 parent 指针。

回复
dfs 2020年10月13日 - 14:30

请问一下现在看博主的Qt学习之路2会不会与qt5不匹配啊?

回复
豆子 2020年10月13日 - 17:18

《Qt学习之路2》就是基于 Qt 5 的,一般不会有问题。新版本增加了额外的 API,但语法之类是完全一致的

回复
K A 2021年2月22日 - 11:07

这篇博文的图貌似都失效了

回复
豆子 2021年2月23日 - 17:09

现在应该好了

回复
kobezz 2021年9月8日 - 15:13

前辈您好,请问学习QT除了C++知识还需要哪些预备知识储备呢?

回复
豆子 2021年9月11日 - 15:53

最好有面向对象编程的基础以及其它一些数据结构之类的基础。

回复

回复 豆子 取消回复

关于我

devbean

devbean

豆子,生于山东,定居南京。毕业于山东大学软件工程专业。软件工程师,主要关注于 Qt、Angular 等界面技术。

主题 Salodad 由 PenciDesign 提供 | 静态文件存储由又拍云存储提供 | 苏ICP备13027999号-2