☰
Ubuntu Qt 环境安装配置指南:从 apt 到交叉编译全攻略
2026/9/25 4:59:45 网站建设 项目流程

在 Ubuntu 上装 Qt 这件事,我前前后后折腾过很多回。第一回是在刚接触 Linux 的时候,以为装个 Qt Creator 就等于装完了 Qt,结果编译一个小窗口程序直接报“找不到 platform plugin”;第二回是在给嵌入式板子交叉编译 Qt 的时候才发现,光装一个桌面版编译器根本不够使;再后来在 Ubuntu 服务器上用 Docker 跑 Qt 自动化编译,又跟 linuxfb 这种平台插件打了一轮交道。装 Qt 这个操作的弹性非常大,简单的一行 apt install 就能搞定,复杂的要手动配交叉工具链和完整依赖,最麻烦的其实是装完之后的各种运行时报错。这篇文章就把我在 Ubuntu 上从零到一安装和配置 Qt 环境的完整经验整理出来,按使用场景分清楚,免得后面没人再踩同样的坑。

1. 安装 Qt 之前,先把需求摸清楚

1.1 先想清楚你拿 Qt 做什么

很多教程一上来就让你上官网下安装包,我反而建议先花五分钟想一个问题:你用 Qt 是跑在哪个环境里的?这个答案直接决定了安装方案。

假如是做桌面应用开发,比如写个跨平台的工具软件、上位机、行业客户端,那么你的重点就是装一套完整的 Qt 开发环境,包含 Qt Creator、对应版本的库文件、CMake 和编译器。这种情况下推荐用官方安装包,或者用系统仓库里的稳定版本,根据项目需求来定。

假如是给嵌入式设备做界面,比如树莓派、RK3588 这类 Linux 开发板,那你光装一个桌面版 Qt 是不够的,还要准备交叉编译工具链和目标设备的 sysroot。这种情况下重点不是“装”,而是“配”——把 qmake 指向交叉编译的配置,把编译产物丢到板子上跑。qt 的下载和安装倒是最不起眼的部分。

假如只是想在 Ubuntu 上写点命令行工具或者带界面的小脚本,那直接用 apt 装系统自带的 Qt 版本就够了,没必要折腾离线包。系统仓库的 Qt 通常和 Ubuntu 的桌面环境集成得很好,性能也够用。

不同的用途决定了安装成本和后续排查方向,这一步想清楚,能省掉后面至少一半的折腾。

1.2 看准 Ubuntu 版本、架构和 Qt 版本

接着看系统本身。在终端里执行两条命令:

lsb_release -a uname -a

lsb_release -a能告诉你当前 Ubuntu 版本号、桌面版本多少;uname -a能看到架构信息,最常见的是 x86_64,树莓派等板子上则是 aarch64。这个信息之所以重要,是因为 Qt 的离线安装包、apt 仓库的包版本和交叉编译工具链都是跟架构绑死的。

再说 Qt 版本选择。Ubuntu 22.04 LTS 的官方源里,Qt 5.15.x 是老牌稳定版,Ubuntu 24.04 则提供了 Qt 6.x 的包。Qt 5 和 Qt 6 的 API 有差异,QML 模块变化也比较大。一般来说:

  • 如果是维护老项目,优先 Qt 5.15.2,LTS 版本,第三方库兼容性最好;
  • 如果是新项目或想用较新的 QML/Quick 特性,优先 Qt 6.2 以上;
  • 如果是嵌入式,还要看目标板子的 BSP 里带的 Qt 版本,这个往往是定死的。

有一点要提醒你:不要在同一台机器上同时使用系统仓库的 Qt 5 和官网的 Qt 6,Python 或者第三方库调用 Qt 时很容易混淆版本,编译时头文件和运行时库对不上,就会冒出一堆奇怪的错误。我后面会专门讲那个“cannot mix incompatible Qt library”的报错,就是典型的版本混用问题。

2. 两条安装路径:系统仓库和官方安装包

2.1 最省事的方式:apt 直接装

如果只是做桌面开发,或者想快速跑起来验证一下,用 apt 是最省事的。以 Ubuntu 22.04 为例,执行:

sudo apt update sudo apt install qt6-base-dev qt6-tools-dev qtcreator cmake g++

需要 Qt 5 的话:

sudo apt install qtbase5-dev qttools5-dev qtcreator

这里qtbase5-dev提供 Qt 的核心模块和开发头文件,qttools5-dev提供 uic、moc、rcc 等辅助工具,qtcreator就是那个集成开发环境。cmake和g++是 Qt6 项目默认的编译工具链,缺一个都会在建 Kit 的时候卡住。

安装完成后,你可以直接运行qtcreator启动 IDE,在“工具 -> 选项 -> Kits”里确认编译器已经被自动识别。apt 装的 Qt 有一个很大的好处:它由系统包管理器统一管理,卸载干净,不会留下手动安装时的残留文件。缺点也很明显:版本更新慢,官方源里的 Qt 往往落后于官网几个小版本,对某些新特性要求高的项目可能不够。

另外,如果你发现sudo apt install qtcreator之后,编译 Qt 连GL/gl.h都找不到,那是缺了 OpenGL 开发库。Qt 的窗口渲染底层依赖 OpenGL,所以推荐把这些包也装上:

sudo apt install libgl1-mesa-dev libglu1-mesa-dev libxkbcommon-x11-dev libxcb-xkb1 libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-render-util0-dev

这些包看起来不起眼,实际上很多运行时报错都是因为它们没装全导致的。就算你用 apt 能打开 Qt Creator,缺了这些库也可能会在运行动态库时报错,到时候定位半天,其实只是少装了一个 xcb 插件依赖。

2.2 更可控的方式:官方离线安装包

对于需要特定 Qt 版本、特殊模块或者嵌入式定制版 Qt 的场景,推荐去 Qt 官网下载离线安装包。在下载页面里找到qt-opensource-linux-x64-5.15.2.run一类的文件,注意区分 Linux 那个版本号。下载完记得授权执行:

chmod +x qt-opensource-linux-x64-5.15.2.run sudo ./qt-opensource-linux-x64-5.15.2.run

执行之后进入图形化安装界面,需要登录 Qt 账号,组件列表里选择你要的版本和模块。这里有个经验点:只勾需要的组件,别贪多,安装 Qt 的组件越多,硬盘占用越大,而且不同模块之间的依赖越复杂。最典型的组合是:

  • Qt 5.15.2主库;
  • Qt CreatorIDE;
  • Development and Designer tools里面的 Qt Designer 单独运行工具;
  • 如果你要交叉编译,还可以在安装器里勾上对应平台的 qmake。

不过离线安装包有个很坑的地方:它默认装到/opt/Qt5.15.2这类目录下,普通用户对该目录只有读权限,安装完成之后生成的临时文件和缓存在~/.config里,一般不会有权限问题。但编译项目的时候,如果项目工程文件里自动写了绝对路径,建议检查一下路径是不是真的指向了你安装的目录。我碰上过好几回,明明装的是 5.15.2,工程文件里却写的是 5.15.0 的构建目录,结果编译时各种找不到头文件。这个问题早期特别容易忽略。

2.3 装完第一件事:检查编译器、qmake 和 CMake 是否在同一个“同步轨道”

不管用哪条安装路径,装完之后推荐立刻在终端里检查三条命令:

qmake -v cmake --version g++ --version

如果qmake -v弹出来的版本跟你预期的不一致,比如你在/opt里装了 Qt 5.15.2,但qmake指向的却是/usr/bin/qmake,那说明 PATH 里系统包的优先级更高。这时候要么重设 PATH,要么在权限设置里面明确指定 qmake 的路径。这个问题很常见,尤其在同时使用 apt 和官方包的时候。

cmake 也要注意版本,Qt6 要求 CMake 3.16 以上,某些早期版本 Ubuntu 自带的 cmake 太老,会编译失败。如果版本不够,可以先:

sudo apt upgrade cmake

或者用官方 pip 安装的 cmake 作为替代。实际工作中我发现,如果项目是能选择 QMake 来构建,通常直接用 Qt 自带的 QMake 就能解决很多问题,因为 CMake 处理不好时,出错信息极其难排查。

3. 配置 Qt Creator、Qt Designer 和环境变量

3.1 Kit 配置里到底发生了什么

Qt Creator 里的“Kit”是把编译器、调试器、Qt 版本和 CMake 工具都合并成一个构建环境。如果你只安装了一个 Qt 版本,它通常能自动识别;但当你手动离线安装后,在 Qt Creator 的“工具 -> 选项 -> Kits”里可能看不到新安装的 Qt 版本,是因为没有把它注册进去。

具体操作:在“Qt Versions”标签页,添加/opt/Qt5.15.2/5.15.2/gcc_64/bin/qmake,让它扫描到这个 Qt 库。然后在“Kits”标签页新建一个 Kit,把编译器、调试器和 Qt 版本都选到对应的项。这里有一个经常被忽略的地方:编译器不是“选一个就行”,C编译器要选gcc,C++编译器要选g++,如果只填了 C++ 编译器,有些项目在解析 C 源文件时候就会报找不到头文件。

还有一点:如果你做的是 QML 开发,建议额外安装qml-module-qtquick2这类模块,否则在 Qt Creator 里打开 QML 文件会提示各种模块缺失。桌面 Ubuntu 下系统源里可以安装一部分,但如果你用官方包,则直接下载对应的源模块进行编译也没问题。

3.2 想单独用 Qt Designer 的话

Qt 官方把 UI 设计工具叫 Qt Designer,在 Qt Creator 里虽然也有集成,但很多人不知道它还可以单独跑。单独跑的好处是可以脱离整个 IDE,快速设计.ui文件然后直接交给同事或者脚本去构建。在 apt 安装的路径下,运行:

designer

启动之后就是独立的界面编辑器,左上角是控件面板,中间是画布,右下角是属性编辑器。如果你是从官网安装的,designer在/opt/Qt5.15.2/Tools/QtCreator/bin里也带一个,但那个版本通常跟 IDE 绑定的比较紧,独立运行时反而会遇到平台插件的问题。

要我说,真正高效的用法是:UI 复杂的时候单独开 designer 来拖控件,保存.ui文件进工程,这样比在 Creator 里切来切去顺畅得多。尤其在你需要做批量界面调整的时候,独立 designer 可以开多个窗口对比观察,方便不少。

开发过程中生成.ui文件后,一般不需要手动跑 uic,编译项目时 qmake 或 cmake 会自动把.ui文件转换成ui_xxx.h头文件。新手容易犯的错误是改了.ui之后没有重新编译,导致代码里引用的控件已经改名了,但编译后还是找不到对应控件。这个问题的解决办法就一个:改完.ui一定重新make clean或者rm -rf build再重新构建一次。

3.3 PATH 和 LD_LIBRARY_PATH 的坑

装完 Qt 之后,把 Qt 的 bin 目录加进 PATH 是常规操作。编辑~/.bashrc加入:

export PATH="/opt/Qt5.15.2/5.15.2/gcc_64/bin:$PATH"

如果安装目录不是你的家目录,还要考虑LD_LIBRARY_PATH的问题。Qt 运行的时候需要加载 Qt 的动态库,系统默认搜索路径里往往没有/opt/Qt5.15.2/5.15.2/gcc_64/lib,所以可以:

export LD_LIBRARY_PATH="/opt/Qt5.15.2/5.15.2/gcc_64/lib:$LD_LIBRARY_PATH"

这里我必须把丑话说在前面:依赖LD_LIBRARY_PATH作为长期的解决方案,是一个很隐蔽的坑。很多临时变量会导致系统其它软件产生莫名的链接冲突,比如你某天运行系统的 Python 或 PyQt5 程序,发现它开始报 Qt 版本混乱,很可能就是这个变量把系统的库搜索路径带偏了。所以,如果只是开发用,可以接受;如果是部署到生产环境,建议使用 Qt 自带的qt.conf文件或者直接在程序目录配置好 RPATH,而不是依赖全局环境变量。

qt.conf的做法是在可执行文件旁边放一个文本文件,写入:

[Paths] Prefix=/opt/Qt5.15.2/5.15.2/gcc_64

这样程序启动时会自动根据这个 Prefix 找到对应的 Qt 库,不污染系统环境。这个技巧对部署特别管用,但实际项目里见到有人用的人很少。

4. 创建第一个项目并验证环境

4.1 在 Qt Creator 里创建 Widgets 项目

打开 Qt Creator,菜单“文件 -> New Project”,选择“Qt Widgets Application”,填上项目名比如hello_qt。在构建系统一栏,如果你用的是 Qt5.15 且没有特别需求,选 qmake 比较友好;用 Qt6 的新项目则可以直接选 CMake。

后续向导会让你选 Kit,如果你前面已经注册好,直接选对应的 Kit 就行。创建完项目,默认会把main.cpp和一个mainwindow.ui给你生成好,你点击底部的“构建”按钮,看着进度条跑完,再点运行。不出意外的话,一个带菜单栏的窗口会出现在你的桌面上。

这个验证过程不是走个过场。之前我见过一种情况:Qt Creator 能正常构建,但运行时报 “could not find the Qt platform plugin xcb” —— 这类问题跟 Creator 没关,是系统库里缺少 xcb 相关的零散包。出现这种错误,就按照前面 2.1 里我列的那串libxcb-*包从头装一遍,基本能解决。

4.2 不用 IDE,命令行动手走一遍

除了用 IDE,我更推荐你手动跑一遍命令行构建流程,这样才能真正理解 Qt 的构建机制。在项目目录里创建CMakeLists.txt或使用.pro文件。以 qmake 的方式举例,写一个最小的hello.pro:

QT += widgets SOURCES += main.cpp TARGET = hello_qt

然后执行:

qmake hello.pro make -j$(nproc)

如果一切正常,同目录下会生成hello_qt可执行文件。运行:

./hello_qt

一个小问题:如果你是 X11 桌面环境,窗口可能一闪而过,控制台也没输出。这不是错误,只是程序本身没有阻塞式逻辑。为了确认它有没有跑起来,可以直接在 main.cpp 里加一行输出到终端验证,但其实没必要,你能看到窗口就说明环境正常。

如果你在无桌面的服务器上测试,运行后终会报错,因为找不到 Linuxfb 平台插件,这就是我后面要专门说的嵌入式场景问题。在桌面上运行则不需要特别指定平台插件。

4.3 验证 Qt 动态库是否匹配

命令行构建成功后,还可以用 ldd 检查可执行文件到底链接了哪里的 Qt 库:

ldd ./hello_qt | grep Qt

如果你明明装了官网的 Qt,却看到输出里出现/usr/lib/x86_64-linux-gnu/libQt5Core.so.5,说明它链接的是系统 apt 源里的库,不是官网的库。这种错乱会造成版本不匹配,运行时会报很难查的错。

要强制让程序使用某套库,一个是在构建时指定-rpath,另一个就是写qt.conf。对小程序来说,直接用LD_LIBRARY_PATH排在最前面试一次也能看效果,但最终方案还是要做到库路径可移植。

5. 常见问题排查与避坑手册

5.1 一张表先解决一半问题

下面这张表我在每次记笔记时都会想起来,整理成速查表分享给大家。适用最常见的桌面 Ubuntu 装 Qt 的报错:

报错信息典型原因处理方式
cannot mix incompatible Qt library (version ex50601) with this library编译时链接的 Qt 版本和运行时加载的 Qt 版本不一致统一 LD_LIBRARY_PATH,确认 qmake 和运行库路径一致
could not find the Qt platform plugin "linuxfb"系统没有 plugins/platforms 目录下的 libqlinuxfb.so,或没有指定平台插件路径在可执行文件旁设置 qt.conf,或安装/拷贝对应插件;无桌面时设置QT_QPA_PLATFORM=linuxfb
cannot find -lpublic链接器找不到名为 public 的库文件libpublic.so确认库文件路径,用-L/path/to/lib指定搜索目录
GL/gl.h: No such file or directory缺少 OpenGL 开发库安装libgl1-mesa-dev libglu1-mesa-dev
QXcbConnection: Could not connect to display程序连接到 X 服务失败,常见于无图形界面环境确保 DISPLAY 变量正确;用xvfb-run或者 SSH 启用 X11 转发
:-1: error: Unknown module(s) in QT: xxx缺少对应 Qt 模块开发包安装对应模块,如sudo apt install qtdeclarative5-dev

5.2 最糟心的 “cannot mix incompatible Qt library” 是怎么回事

这个词我是真正见识过才能体会的。某次我帮朋友查一个项目,程序编译一把过,运行时立刻报这种“版本不兼容”。这里的version ex50601是指编译时用的 Qt 版本内部表示:5.6.1会编码成类似 0x50601 的数值,5.15.2则会编码成更大的一个数值。报错的本质是:程序在加载一个动态库的时候,它头文件里记录的 Qt 版本和运行时暴露的 Qt 版本集合对不上。

为什么会这样?因为编译时qmake指示的是/opt/Qt5.15.2/.../lib里的库,而运行时动态链接库搜索顺序却先找到/usr/lib/x86_64-linux-gnu/libQt5Core.so.5,也就是系统自带的库。两边版本不一致,Qt 内部的 version marker 拼起来对不上,程序就拒绝加载。

排查的方向很简单:先ldd看动态库指向,再看看qmake -v指向,最后看LD_LIBRARY_PATH和qt.conf。我最终是把 /opt 的 bin 目录加到了 PATH,同时给程序目录写了一版 qt.conf,彻底屏蔽了系统库的干扰。

5.3 在无桌面的服务器或嵌入式板子上跑 Qt,linuxfb 插件缺了怎么办

这个报错在纯命令行服务器、Docker 容器和嵌入式板子上几乎天天见。Qt 的抽象其实早就准备好了:它支持 xcb(桌面环境)、linuxfb(直接写 framebuffer)、eglfs(基于 EGL)等多种平台插件。默认QT_QPA_PLATFORM=xcb,如果你的环境中没有 X server,Qt 就会尝试回退到其它插件,但此时插件目录里如果没有libqlinuxfb.so就会报 this 错误。

解决方式有两层。第一层:在环境变量里指定用 linuxfb:

export QT_QPA_PLATFORM=linuxfb ./hello_qt

但前提是程序编译时启用了linuxfb插件,否则依然报错。Qt 默认源码编译时会包含该插件,但在某些精简版安装里可能没有。第二层:确认插件存在后再指定。可以在 Qt 安装目录里搜索:

find /opt/Qt5.15.2 -name "*linuxfb*"

如果插件不存在,就需要你重新编译 Qt,或者在构建 Qt 时通过-plugin-linuxfb选项让它生成。这里还要注意权限问题:使用 linuxfb 时程序往往需要能访问/dev/fb0,如果权限不足,运行会直接 Segmentation fault 或没有反应。排查时可以先用ls -l /dev/fb0看看这个设备节点是否存在,并确认当前用户有没有权限。

5.4 链接器报 “cannot find -lpublic” 的排查思路

这个报错看起来其实和“无法找到对应 Qt 模块”很像,但根本原因是你在链接参数里通过-lpublic指定了一个名为public的库。某些第三方项目或自研库会把公共部分汇总成一个叫libpublic.so或libpublic.a的文件,实际开发中我见过一些团队这么组织代码。如果你的LIBS += -lpublic但链接器没找到,说明libpublic.so不在链接器的默认搜索路径下。

解决办法是明确指定库路径:

LIBS += -L/path/to/lib -lpublic

也可以用INCLUDEPATH来指定头文件目录,避免头文件搜索不到。这里最容易被忽略的是:如果你用的是 CMake,那么应该用target_link_libraries(your_target PUBLIC /path/to/libpublic.so),直接把.so的完整路径传进去,这样就不会牵扯到-l搜索顺序的问题。

5.5 中文输入法在 Qt Creator 里用不了

这个问题不是 Qt 的 bug,而是输入法框架和前端的对接问题。在 Ubuntu 桌面环境下,常见输入法有 fcitx5 和 ibus,Qt 程序需要通过对应的输入法插件访问输入法服务。如果你发现 Qt Creator 里能输入英文,但不能切换中文,优先检查有没有安装输入法前端库。

以 fcitx5 为例,需要安装:

sudo apt install fcitx5-frontend-qt5

装完重启 Qt Creator,输入法就正常了。如果是 ibus,检查环境变量GTK_IM_MODULE、QT_IM_MODULE、XMODIFIERS是否配置正确。这个问题的排查方式和普通 GTK / Qt 应用几乎一样,所以你在网上搜到的“Ubuntu 中文输入法怎么设置”教程,原理是相通的。

6. 进阶玩法:交叉编译和 Docker 容器里的 Qt

6.1 交叉编译:给树莓派这类 ARM 板子准备 Qt 环境

交叉编译是很多 Linux 下 Qt 应用真正要面对的核心挑战。拿最常见的树莓派举例,你在 Ubuntu x86_64 电脑上交叉编译一个 ARM 版本的 Qt 程序,需要三样东西:交叉编译工具链、目标板的 sysroot、编译好的 Qt for ARM 库。

完整流程一般是:先在树莓派上装同版本 Ubuntu 系统,拷出根目录/的一部分作为 sysroot,然后在电脑上下载交叉编译器,比如aarch64-linux-gnu-g++,最后用 Qt 源码配合脚本配置交叉编译参数,指定目标平台架构、sysroot 路径和编译选项。这是一套工程量庞大的流程,主要难点在于处理 sysroot 的依赖库问题,以及 Qt 的 configure 选项能不能和你手上的编译器版本匹配。

这里我给你一条务实的建议:不是每个项目都需要自己编译 Qt 库。如果你的板子厂商已经提供了 Qt 二进制包或者 SDK,直接用它的库来交叉编译你的应用程序就行,没必要从源码把整个 Qt 重新编译一遍。只有当你需要修改 Qt 源码或者对平台插件有特殊定制需求时,才值得去重新源码编译 Qt。

交叉编译时一个常见的坑是“run on target”配置错误。在 Qt Creator 里新增一个 Kit,把“Device”配置成一个 SSH 连接到树莓派的设备,编译时它能自动把编译产物部署到板子上。但如果你不配置 Device,只改编译器为交叉编译器,程序虽然在 x86 上能编译,但运行前就会直接在板子上缺失库文件。

6.2 在 Docker 容器里跑 Qt 程序,CI 和二进制部署

在持续集成流程里用 Docker 容器编译 Qt 应用是个很常见的需求。在容器里装 Qt 和宿主机上一样,但要注意的是,你想在容器内显示 GUI 的时候,容器默认是没有 X server 的。该怎样处理呢?常见做法是把宿主的 X11 socket 挂到容器内:

docker run -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ your_qt_image ./hello_qt

这种方案在本地跑没问题,布局也非常直观。但它依赖宿主机的 X 服务,在 CI 环境里不一定可用。CI 环境里通常用两种方式:一种是设置QT_QPA_PLATFORM=offscreen,用离屏渲染模式测试程序逻辑;另一种是安装 Xvfb 作为假 X server。单独要跑图形测试还会用到 OpenGL 相关的虚拟驱动,这时候追根到底又是一堆依赖问题。我在 CI 里最常用的指令其实很简单:

xvfb-run -a ./hello_qt

如果还需要启用 linuxfb 做一些 framebuffer 层面的验证,再配合QT_QPA_PLATFORM=linuxfb来运行。平常在本地桌面 Ubuntu 上装 Qt 之后,这种容器化的经验虽然用不上,但一旦你接入自动化编译和发布流程,就是刚需。

我个人的实操体会是,装 Qt 这个动作本身并不复杂,真正花我时间最多的是那些“装完过后的错误处理”和“编译路径的选择”。与其在各个论坛上搜索报错信息,不如一开始就把版本、库路径和依赖装齐。如果大家在实际配置过程中还遇到其它没见过的问题,也建议先拿ldd和qmake -v这两个命令定位,它们能带你少走至少一半的弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询