资讯动态

Qt6入门必看:从环境配置到Hello World窗口程序完整指南

发布时间:2026/9/18 8:13:29 来源:尧图企业网站定制
说实话每次看到有人把“Hello World”跑通之后发朋友圈我都觉得那是程序员生涯里最纯粹的几秒钟之一。大一那年我在终端里敲出第一行C语言printf的时候屏幕上的中文乱码成一片我愣是盯着看了五分钟最后发现是编码问题改完之后那种“成了”的感觉到现在还记得。到了Qt这里其实是一样的心情——只不过这次你面对的不再是黑底白字的终端而是一个能拖、能拽、能点按钮的图形窗口。这篇教程是Qt6入门系列的第三篇聚焦在最核心也最容易被忽略的一步创建并真正理解一个Qt6的Hello World项目。我们会从环境准备、工程文件结构、代码逐行拆解到编译运行以及常见报错一路走完全流程。适合刚装好Qt、还没写过一行Qt代码的初学者也适合以前用过Qt5、想看看Qt6有哪些变化的老朋友。网上关于Qt6的教程其实不少但很多都跳过了“为什么”这一步直接告诉你“点这里、点那里”结果换个环境、换个版本就抓瞎。这篇不一样我会把每一步背后的逻辑讲清楚你照着做能跑通做完之后换台电脑、换个项目也能自己折腾。1. 环境准备别急着写代码先把“坑”填平很多新手在Hello World这一步就放弃了不是因为代码难而是因为环境压根没配好。Qt的安装和配置说简单也简单说麻烦也麻烦主要看你怎么选。我个人的建议是如果你是纯新手尤其是之前在Windows上做C/C课程设计的那种直接装Qt官方的在线安装包选MinGW 64-bit套件别的先别动。1.1 Qt6安装时到底该怎么选组件打开Qt的在线安装程序之后会让你登录Qt账号然后进入组件选择界面。很多人到这里就懵了一大长串列表什么Qt 6.8.2、Qt 6.5.3、Additional Libraries、Developer and Designer Tools全勾怕占空间不勾又怕缺东西。我给你的建议很简单第一步展开你需要的那个Qt版本号比如Qt 6.8.2只勾选“MinGW 11.2.0 64-bit”这一个编译套件下的内容其他平台比如MSVC 2019、Android、WebAssembly统统不勾。第二步在Developer and Designer Tools里勾上“MinGW 11.2.0”和“CMake”和“Ninja”——这几样是编译必备的。第三步直接下一步安装。为什么这么选先说为什么选MinGW而不是MSVC。MinGW是Windows上的开源C/C编译器GCC的Windows移植版它跟Qt配合最省心不需要额外装Visual Studio那一大坨东西。MSVC需要你单独装Visual Studio的C开发组件而且不同VS版本的兼容性问题很烦。新手阶段用MinGW编译命令简单报错信息相对友好跑通最重要。再说为什么只勾64-bit。现在的Windows基本都是64位系统装32位版本虽然也能跑但后续如果你要装一些第三方库64位库的选择面广得多。除非你是给老机器做兼容否则64位永远是首选。注意安装路径千万别带中文和空格比如“C:\Qt”就很好。我之前见过有人装在“D:\软件\Qt”下面编译的时候各种莫名其妙的报错花了一晚上排查最后把路径改成纯英文一次通过。这不是玄学是很多构建工具对中文路径的支持确实有问题。安装完之后验证环境是否正常打开Qt Creator看左下角的“套件选择器”Kit Selector如果能看到类似“Qt 6.8.2 MinGW 64-bit”的选项说明套件识别正常。这时候别急着写代码先编译一个空项目试试确保编译器、构建工具、Qt库三者之间的链路是通的。1.2 环境变量与命令行编译的基础认知虽然Qt Creator已经帮我们处理了90%的环境问题但作为开发者你迟早要学会在命令行里编译Qt项目。这不只是装酷很多时候排查问题、写自动化脚本、用vscode开发Qt项目都得靠命令行工具链。安装完Qt之后在开始菜单里能找到“Qt 6.8.2 (MinGW 11.2.0 64-bit)”这个文件夹里面有个快捷方式叫“Qt 6.8.2 MinGW 11.2.0 64-bit Command Prompt”。点开它你会发现一个已经配置好PATH环境变量的命令行窗口。在这个窗口里你可以直接使用qmake、cmake、mingw32-make、g这些命令。验证一下在命令行里输入“g --version”如果能正常显示GCC版本信息说明编译器可用输入“qmake --version”如果显示QMake version 3.1之类的信息说明Qt的构建工具也可用。这两条命令都通过你的命令行编译环境就算备好了。后面我们在第4部分会讲到如何完全用命令行编译运行Qt程序那时候你就明白为什么要在这里多花两分钟做验证了。2. 创建Hello World项目的两种正规姿势在Qt6时代创建项目主要有两种方式一种是用Qt Creator图形界面创建简单快捷适合大多数新手另一种是纯手写工程文件然后用命令行编译适合想搞清楚背后原理的人。我建议你先用图形界面跑通一遍再手动建一遍两遍下来你对Qt项目的理解会彻底不一样。2.1 用Qt Creator图形界面创建项目打开Qt Creator点击左上角的“文件”菜单选择“新建项目”。在模板选择界面里左侧选“Application (Qt)”右侧选“Qt Widgets Application”然后点击“Choose”。这里注意别选错因为模板列表里还有“Qt Console Application”和“Qt Quick Application”前者做不了图形窗口后者是QML语言的都不是我们这篇要讲的。接着填项目名称比如“HelloWorld”创建路径选一个纯英文路径比如“D:\QtProjects”。这里有个容易忽略的选项——“创建项目目录”默认是勾上的意思是项目文件会放在“D:\QtProjects\HelloWorld”里。看着多余其实是个好习惯每个项目一个独立文件夹后面资源文件、头文件、源文件都往里面塞不会乱。构建系统那一页Qt Creator会让你选“CMake”还是“qmake”。Qt6时代CMake是官方主推的构建系统所以默认就是CMake直接用就行。qmake是Qt5时代的主力虽然Qt6继续兼容但新项目别再用qmake了学习成本高且生态在逐步迁移。然后是“翻译文件”那一页直接跳过。再然后的“套件选择”页面确认只勾选了MinGW 64-bit那一个套件点下一步。最后看一遍“项目配置”摘要点“完成”一个Hello World原型的代码就自动生成了。此时Qt Creator会自动打开两个文件main.cpp和CMakeLists.txt。点击左下角的绿色三角“运行”按钮如果一切顺利你会看到一个空白的窗口弹出标题栏显示“HelloWorld”——恭喜你其实已经完成了一个最基础的Qt程序连代码都没写一行。2.2 纯手写工程文件体验一次真正的“从零到一”用Qt Creator自动生成的代码作为起点固然省事但是如果你不懂那些代码在干什么换个场景照样蒙圈。我建议你回到命令行纯手写一遍。这种“笨办法”看起来慢实则是建立底层认知的最快路径。在纯英文路径下建一个名叫“HelloWorldManual”的文件夹里面新建两个文件main.cpp和CMakeLists.txt。用任何一个文本编辑器都可以别用记事本就行推荐VS Code或者Notepad。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(); }CMakeLists.txt的内容cmake_minimum_required(VERSION 3.16) project(HelloWorldManual VERSION 1.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) qt_standard_project_setup() qt_add_executable(HelloWorldManual main.cpp ) target_link_libraries(HelloWorldManual PRIVATE Qt6::Widgets)这两份文件的作用和每一行的含义我会在3.2和3.3部分详细拆。你先照着建好就行。2.3 构建系统二选一为什么只谈CMake除了CMakeQt项目还有一种传统构建方式——qmake它的工程文件后缀是.pro。如果你在网上搜索Qt教程十篇里有八篇还在用qmake原因很简单老的教程写于Qt5时代那时候qmake是默认配置。但我要明确告诉你在Qt6时代官方已经把CMake作为首选构建系统。Qt6的官方文档、示例代码、新功能适配全部优先CMake。很多新出的Qt模块甚至直接不再兼容qmake。所以不管你在网上看到多少qmake的教程新项目请直接上CMake。CMake的好处是什么它是一个跨平台的构建工具你的同一份CMakeLists.txt在Windows上能编在macOS上能编在Linux上也能编代码完全不用改。而且CMake不止用于Qt整个C开源生态几乎都在用CMake你学一次终身受用。qmake只服务Qt生态离开Qt基本就是废技能。3. 逐行拆解Hello World不是会复制粘贴就算会了很多新手写Hello World就是一个动作复制、粘贴、运行、看到窗口、截图发朋友圈、完事儿。我建议你多花十分钟把每一行代码和每一行构建配置弄明白。这一步的深度决定了你后面学布局、信号槽、自定义控件时是“通”还是“堵”。3.1 main.cpp里的四个关键角色第一行#include QApplication引入了QApplication类。这玩意儿是Qt GUI程序的“心脏”它负责管理整个应用程序的控制流和主要设置。简单说你的程序要想有窗口、能响应系统的鼠标键盘事件就必须有一个QApplication对象。第二行#include QLabel引入的是标签控件。QLabel是Qt最简单的控件之一它的职责就是在窗口上显示一段文本或图片。这里我们让它在屏幕上显示“Hello World!”。接下来看main函数内部QApplication app(argc, argv);这行创建了一个QApplication对象叫app。argc和argv是命令行参数从main函数的参数直接转发过来。这一步非常关键——在创建任何窗口、任何控件之前必须创建QApplication对象。你可以把它理解成“搭台子”没有台子后面的戏就没法唱。QLabel label(Hello World!);在栈上创建了一个QLabel对象文本内容就是“Hello World!”。注意这个label是局部变量离开main函数作用域就会销毁但Qt的对象树机制会保证它在合适的时机被处理——不过目前我们还没把这个label放进一个真正的窗口里它自己是顶层窗口。label.show();显示这个label。这一步太重要了因为默认情况下Qt控件是隐藏的。如果你忘了写show()程序运行起来啥也看不见而且不会报错——我当年就因为这个卡了半小时以为代码出问题了结果只是少了一行。return app.exec();让QApplication进入事件循环。事件循环是GUI编程的核心概念程序进入一个死循环不停地处理窗口重绘、鼠标点击、键盘按键等事件直到用户关闭窗口这个循环才退出程序结束。Qt的窗口之所以能实时响应操作就是这个事件循环在背后撑腰。这段代码一共也就七八行但每一行都是刚需少了任何一行都不行。这也是我坚持让新手看代码而不是依赖Qt Creator自动生成代码模板的原因——模板帮你把细节隐藏了你永远不知道背后发生了什么。3.2 CMakeLists.txt逐行拆解很多人一看到CMakeLists.txt就头疼觉得又是一门“语言”。其实它的核心逻辑很简单告诉CMake三件事——用什么编译器标准、去哪里找Qt库、把哪几个源文件编译成什么名字的可执行程序。cmake_minimum_required(VERSION 3.16)指定CMake的最低版本。Qt6要求CMake 3.16以上低了会报错。project(HelloWorldManual VERSION 1.0 LANGUAGES CXX)定义了项目名称是HelloWorldManual版本号1.0语言是C。项目名称会参与后面生成可执行文件的命名规则。set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)指定使用C17标准并且这个标准是强制的。如果你编译时C标准不够直接报错而不是警告。Qt6官方要求C17最低你写17是底线写20也行但没必要。find_package(Qt6 REQUIRED COMPONENTS Widgets)这一行是用来“找到”Qt6库中的Widgets模块。REQUIRED表示找不到就报错COMPONENTS Widgets表示只需要Widgets模块。为什么要单独指定因为Qt把功能拆分成很多模块Widgets管桌面控件Network管网络Sql管数据库。你只用Widgets就没必要把整个Qt全部链接进来能省下大量编译时间和最终的exe体积。后面如果你用到别的模块比如数据库就再加一个Sql。qt_standard_project_setup()这是Qt6引入的一个便利函数它会替你配置一些Qt项目的通用规则。以后你的项目里有资源文件、翻译文件这个函数会自动帮你处理暂时不用管细节照着写就行。qt_add_executable(HelloWorldManual main.cpp)这行和原生CMake的add_executable类似作用是把main.cpp编译成一个名为HelloWorldManual的可执行文件。之所以用qt_add_executable是因为Qt6对源文件做了额外的处理比如自动处理一些Qt特有的元对象编译器moc步骤。这个细节你暂时不用深究知道“Qt项目用qt_开头的函数更智能”就行。target_link_libraries(HelloWorldManual PRIVATE Qt6::Widgets)把Qt6::Widgets这个“库目标”链接到我们的HelloWorldManual可执行文件上。PRIVATE关键字的意思是这个链接关系只在当前目标生效不需要暴露给依赖这个目标的其他目标。写PRIVATE是正确的默认选择不要改成PUBLIC。3.3 两种写法对照QLabel私有窗口 vs QMainWindow主窗口上面HelloWorld是用QLabel作为顶层窗口直接show这是最精简的写法但实际项目里几乎不会这么干。真实项目中你一般会创建一个继承自QMainWindow或QWidget自定义窗口类把控件装到窗口里。下面给一个稍微贴近实际但依然简洁的写法也是Qt Creator模板的简化版#include QApplication #include QMainWindow #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow window; window.setWindowTitle(Hello World); window.resize(400, 300); QLabel *label new QLabel(Hello World!, window); label-setAlignment(Qt::AlignCenter); window.show(); return app.exec(); }这里我们创建了一个QMainWindow作为主窗口设置标题和初始大小然后在堆上new了一个QLabel父对象指定为window。这个父对象指定非常关键Qt对象树机制会接管这个label的生命周期窗口销毁时label自动销毁你不用手动delete——这也是Qt最容易养成的内存管理习惯。上一节代码里label在栈上、没有父对象、自身就是顶层窗口而这一节里label在堆上、有父窗口显示在父窗口的中央。理解这两者的差异你就理解了Qt内存模型和控件层级的最小单元。4. 编译运行图形界面之外的命令行路线到这一步你应该已经在Qt Creator里把项目跑通了。接下来我想带你在命令行里再走一遍完整的构建流程。这不是炫技——当你有一天需要写自动化编译脚本或者偶尔要在没有Qt Creator的环境里编译Qt代码时这个技能能直接救命。4.1 用CMakeNinja从命令行构建Qt项目打开“Qt 6.8.2 (MinGW 11.2.0 64-bit) Command Prompt”切换到你的项目目录比如cd D:\QtProjects\HelloWorldManual先建一个构建目录把生成的临时文件和源码分开。这是CMake的最佳实践别把生成物直接堆在源码目录里否则后面清理起来很痛苦。mkdir build cd build然后执行CMake配置。这一步会读取上一级的CMakeLists.txt检查Qt库、编译器是否符合要求生成构建系统文件cmake .. -G Ninja-G Ninja是让CMake使用Ninja作为底层的构建工具。Ninja是Google出的一个极简高效的构建器比老牌的make快不少Qt6官方默认支持也极好。等两分钟如果一切顺利屏幕上会出现“Configuring done”的字样。再执行ninjaNinja会调用g把main.cpp编译成目标文件再链接成HelloWorldManual.exe。第一次编译会稍微慢一点因为要解析Qt的头文件。看到“ninja: no work to do”或没有报错信息就说明构建成功了。运行.\HelloWorldManual.exe窗口弹出来命令行会一直“卡住”不退出——别慌这不是程序卡死了是事件循环在运行关掉窗口后再看命令就退出了。4.2 Qt Creator构建和命令行构建的结果对比有个细节你可能没注意到Qt Creator底部编译输出里那大串log本质上就是CMake和Ninja的输出。换句话说Qt Creator只是把你手动做的这几步操作封装成了按钮它内部跑的也是CMakeNinja。你在命令行跑的步骤和它在界面里跑的完全是同一套东西。所以如果你在命令行里能手动把项目编译出来再回到Qt Creator里看编译输出你会忽然觉得那些信息不再“看不懂”了。这种感觉很微妙但就是这种“哦原来是这样”一点点改变你对开发工具的认知。提示如果你以后遇到Qt Creator里莫名其妙编译不过但命令行能编译过八成是Qt Creator的缓存坏了。解决办法是“清除项目”后重新构建这也是我在实际工作中排查Qt构建问题的第一步。4.3 链接失败的经典报错找不到“qtmain”很多新手第一次尝试命令行编译时会碰到类似这样的报错cannot find -lqtmain这个qtmain是什么它是Qt提供的一个入口函数库。回想一下你自己的main函数它有一个argc和argv参数但Windows程序真正的入口其实是WinMain——两个入口长得不一样。qtmain库的作用就是干这个“翻译”活的它在背后实现WinMain然后调用你的main(argc, argv)。解决办法很简单在CMakeLists.txt里给可执行文件加一行WIN32选项告诉链接器这是一个GUI程序自动链接qtmainqt_add_executable(HelloWorldManual main.cpp )注意到差异了吗在CMake里你不需要额外加WIN32因为qt_add_executable已经帮你处理了。如果你用原生add_executable(HelloWorldManual WIN32 main.cpp)则需要手动加可那又不是Qt项目推荐的写法。所以强推qt_add_executable它会把这类Windows特性细节全部内部搞定。如果不用qt_add_executable而用原生add_executable链接器没有正确处理GUI入口就会报这个错误。这也是为什么我反复强调Qt6项目要用qt_系列的CMake函数而非native方式——坑已经帮你填平了。5. 常见问题与坑这些坑我踩过你别再踩这一部分全部来自我实际教学和开发中遇到的真实案例每个都有人踩过而且都很典型。5.1 中文乱码问题新手往往喜欢把窗口标题改成中文比如“你好世界”然后发现窗口标题或label显示乱码。Qt6在Windows上默认使用UTF-8编码源码但Windows控制台和相关代码页可能使用GBK二者一旦混淆就容易乱码。解决办法分两类。第一类如果字符串是从代码里直接写死的确保文件的保存编码是“UTF-8 with BOM”然后代码里这样写QString text QString::fromUtf8(你好世界);第二类setWindowTitle里的中文Qt内部把QString存储成Unicode所以理论上用QStringLiteral是最省事的window.setWindowTitle(QStringLiteral(你好世界));关于源码保存编码我用一个办法彻底解决了后续所有烦恼统一把所有源文件编码设定为“UTF-8 with BOM”格式。VS Code里在设置中搜索“files.encoding”改成“utf8bom”即可。这样无论是MSVC还是MinGW都能正确识别中文。5.2 QApplication重复创建导致的崩溃有些新手在一个程序里创建了两个QApplication对象或者重复调用app.exec()程序直接崩溃或行为诡异。QApplication是单实例类一个进程只能有一个。如果你在单元测试或自定义类里也要用到QApplication可以用QApplication::instance()判断是否已经存在存在就不重复创建。重复调用exec()就更危险了——事件循环一旦进入在退出之前它阻塞在那儿你的代码根本走不到下一行“创建另一个QApplication”。所以如果你看到程序卡住或闪退检查是不是有多个exec()嵌套。5.3 忘记调用show()导致的“黑屏”这是Qt新手最经典的“灵异事件”之一程序编译成功了没有报错运行了但一片空白。90%的情况是忘了调用show()。Qt的控件默认是隐藏的show()是把控件显示出来的钥匙。如果在main.cpp里你创建了QMainWindow但忘了调用window.show()那么程序会进入事件循环但是不显示任何窗口。代码看起来是“正常运行”但用户看到的就是一个没有窗口的程序正在后台占资源。这种问题比报错更烦因为完全无提示。5.4 Qt Creator编译报错“cannot find -lQt6Widgets”这个错误一般出现在套件选错或组件没装全的时候。比如你创建项目时选了MSVC套件但安装Qt时只装MinGW——编译器找不到对应的Qt库自然报这个错。解决方法就是回安装程序里把对应的MSVC组件装上或者在套件选择器里切回MinGW套件。另一种情况是CMakeLists.txt里find_package只写了Widgets但代码里用了QtNetwork的类——链接时同样报错。解决方法是检查include了哪些Qt头文件在find_package和target_link_libraries里补全对应的模块。5.5 构建路径有中文或空格导致的诡异错误之前提过一遍这里再展开说深一点。Windows下CMake和Ninja对中文路径的支持向来不好——不是不能用而是某些库的头文件路径拼接中文时会出现编码错乱报出来的错还很奇葩比如整个include路径被截断、打不开某个头文件之类。项目路径、构建路径、Qt安装路径三者都必须保证纯英文、无空格。这是Windows下C开发的基本素养不是什么洁癖。我见过太多新手的报错问题最终指向路径排查了半小时把路径改成英文后秒过。6. 运行效果与后续扩展方向6.1 运行效果全方位解析程序运行后你会看到一个标题栏写着“Hello World”的窗口窗口大小为400x300像素中间位置显示“Hello World!”文本。整个过程从编译到运行如果在命令行里操作大概是5到10秒的事而在Qt Creator里第一次构建会稍慢。运行出窗口的这一刻值得你好好品味一下——这个看似简单的窗口背后实际上发生了好几层事情Windows操作系统创建了一个窗口句柄Qt在内存中创建了对应的控件对象事件循环开始监听窗口被绘制到屏幕上窗体还能用鼠标拖动、缩放、最大化最小化。试着做几个小实验加深理解在代码里修改resize(400, 300)里的数字再重新编译观察窗口默认大小的变化把setWindowTitle里的字符串改成你自己的名字看看标题栏的变化把label-setAlignment(Qt::AlignCenter)注释掉看看文字位置的变化这几个“小动作”能帮你快速感知到“代码和运行效果”之间的关系这一点比死记硬背API重要得多。6.2 下一步怎么走按钮、布局、信号槽如果你已经把Hello World吃透了下一步我建议你试着加一个按钮#include QApplication #include QMainWindow #include QPushButton #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow window; window.setWindowTitle(Hello World With Button); window.resize(400, 300); QLabel *label new QLabel(Hello World!, window); label-setGeometry(100, 100, 200, 50); label-setAlignment(Qt::AlignCenter); QPushButton *button new QPushButton(点击我, window); button-setGeometry(150, 200, 100, 40); window.show(); return app.exec(); }运行之后你会发现click按钮什么都发生。别急那是因为还没写信号槽连接这是下一篇要讲的。Hello World阶段你只要能理解“控件的创建、父对象的指定、窗口的显示”这三个核心动作就够了。等信号槽讲完这整个窗口才能真正“活”起来。6.3 让Qt作品脱离开发环境独立运行最后补充一个很实用的小知识Qt程序编译出来的exe不能直接拷到别的电脑上运行因为它依赖Qt的运行库DLL文件。你需要在Qt安装目录的bin文件夹里找到对应的DLL比如Qt6Widgets.dll、Qt6Core.dll、Qt6Gui.dll还有platforms文件夹下的qwindows.dll一并拷贝到exe同级目录。不过手动拷贝DLL容易漏Qt官方提供了windeployqt工具一行命令搞定windeployqt.exe HelloWorldManual.exe在Release模式下编译出exe后在命令行执行这条命令它会自动分析exe依赖的Qt库把需要的DLL复制到当前文件夹。做完这一步整个文件夹就可以打压缩包发走到别的电脑上解压就能直接双击运行。注意windeployqt处理的是release版exedebug版依赖更多且不需要外发。回顾一下我们在Qt6里创建Hello World项目的完整路径是装好Qt和MinGW套件创建一个CMake工程写一个main.cpp用CMakeLists.txt把Qt6::Widgets链接起来跑起来看到一个窗口。单看每一步都不难但拼接在一起就是无数新手过不去的坎。我个人的体会是入门阶段最值得投资的不是背API而是把一个最小项目彻底吃透。每一行代码都懂、每一步构建都明白、每一个报错都能自己查——这个基础打牢了后面Qt的博大精深你才有底气去接。如果你在跟着实操的过程中遇到任何问题把这几个检查项过一遍路径有没有中文、套件选没选对、CMake配置有没有成功、show()调了没有百分之八十的问题都能自己解决。环境一旦对了写Qt代码是真的会越写越顺手。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价