尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

嵌入式Linux开发板Qt程序从零到一:环境搭建、交叉编译与部署实战

嵌入式Linux开发板Qt程序从零到一:环境搭建、交叉编译与部署实战
📅 发布时间:2026/7/29 4:58:02

1. 项目缘起:从零到一的嵌入式Qt初体验

在嵌入式开发这个行当里,把第一个图形界面程序跑在开发板上,就像小时候第一次成功点亮一个LED灯一样,有种难以言喻的成就感。我手头这块板子,是一块基于ARM Cortex-A7内核的T113开发板,资源不算丰富,但跑个Qt应用绰绰有余。很多朋友一提到嵌入式图形开发,就觉得门槛高、环境复杂,尤其是Qt,感觉要配交叉编译工具链、移植库、搞根文件系统,头都大了。其实,只要理清脉络,避开几个常见的坑,从零到一的过程可以非常顺畅。今天,我就把自己在Linux开发板上跑通第一个Qt程序的全过程,包括踩过的坑和总结的技巧,原原本本地记录下来。无论你用的是T113、RK3588还是F1C100s,这套思路都是相通的,目标就是让你在板子上看到一个自己写的窗口弹出来。

2. 环境准备与核心思路拆解

2.1 为什么选择Qt for Embedded Linux?

在嵌入式领域做图形界面,选择不少,有DirectFB、MiniGUI、LVGL,还有Qt。我选择Qt,主要基于几个现实的考量。首先,是生态和开发效率。Qt Creator这个IDE对开发者太友好了,拖拽控件、信号槽编辑器、一体化调试,能省下大量手动编写界面布局和事件处理代码的时间。对于从零开始的个人项目或小团队,快速出原型至关重要。其次,是跨平台特性。虽然我们目标平台是ARM Linux开发板,但99%的界面开发和逻辑调试工作都可以在x86的Windows或Linux主机上完成,使用Qt的桌面版本进行模拟和测试,极大提升了开发效率,最后只需要交叉编译一次部署到板子。最后,是功能的完备性。从简单的按钮、文本框到复杂的图表、3D渲染,Qt都提供了成熟的模块(Qt Widgets, Qt Quick),避免了重复造轮子。当然,它的“重”也是众所周知的,需要为板子准备足够的存储空间和内存,这也是为什么我选择了内存512MB的T113,而不是更拮据的MCU级别开发板。

2.2 开发环境搭建全景图

整个环境涉及三个部分:宿主机(Host)、交叉编译工具链(Toolchain)和目标板(Target)。宿主机就是你的开发电脑,我用的是一台Ubuntu 22.04的PC。目标板就是T113开发板,上面已经跑着一个精简的Linux系统(内核版本5.4)。而工具链,则是连接两者的桥梁,它是一套运行在宿主机上、但能生成ARM架构可执行程序的编译器、链接器和库的集合。

这里有一个关键决策点:是自己从源码编译Qt库,还是使用开发板厂商提供的SDK?对于第一个程序,我强烈建议选择后者。像友善之臂、全志等厂商,通常会为其开发板提供完整的SDK包,里面已经包含了适配好板子硬件(比如GPU、显示驱动)的Qt库和工具链。自己编译Qt源码虽然更灵活,但光是配置参数、解决依赖就可能耗去一两天,对新手极不友好。我这次使用的就是T113 SDK中提供的gcc-linaro-6.3.1工具链和预编译好的Qt 5.12.8库文件。

宿主机环境清单:

  • 操作系统:Ubuntu 22.04 LTS
  • 必要软件包:通过sudo apt install安装build-essential,libgl1-mesa-dev(OpenGL库,Qt编译可能需要),git,cmake等。
  • 开发工具:Qt Creator 8.0.2(直接从Qt官网下载的在线安装器安装)。注意,安装Qt Creator时,只需要选择安装桌面版本的Qt套件(比如Qt 6.5.2 for Desktop),用于在主机上设计和调试。我们不需要在主机上安装ARM版本的Qt。

目标板环境确认:

  • 通过串口终端登录开发板,检查关键信息:
    # 查看内核架构,确认是ARM uname -a # 查看显示框架,常见的有framebuffer (/dev/fb0) 或 Wayland/Weston ls /dev/fb* # 检查是否有EGL/GLES库,这对Qt Quick加速很重要 ls /usr/lib/libEGL* /usr/lib/libGLES*
    我的板子使用的是framebuffer (/dev/fb0) 和EGL/GLES 2.0,这是嵌入式Qt的典型配置。

3. 第一个Qt程序:从创建到交叉编译

3.1 在Qt Creator中创建并设计桌面版本

首先,我们在宿主机上用Qt Creator创建一个最简单的Qt Widgets应用,项目名就叫HelloEmbeddedQt。这一步和普通的桌面Qt开发没有任何区别。在设计师界面,我拖入了一个QLabel,写上“Hello, Embedded Qt!”,又加了一个QPushButton,按钮上写着“Click Me”。然后,为按钮的clicked信号关联一个槽函数,让点击按钮时,Label的文本变成“Button Clicked!”。

这个步骤的核心目的是验证业务逻辑。所有按钮响应、文本更新、界面布局的调试,都在性能强大的宿主机上完成,使用我们熟悉的调试工具,效率极高。完全不需要在编译慢、调试难的开发板上进行。

3.2 配置Qt Creator的交叉编译套件(Kit)

这是最关键的一步,告诉Qt Creator如何为ARM板子编译程序。在Qt Creator的“项目”模式侧边栏,我们需要配置两个东西:编译工具链和Qt版本。

  1. 配置编译器:

    • 进入工具->选项->Kits->编译器。
    • 点击“添加”,选择“GCC” -> “C++”。
    • 在“编译器路径”里,浏览到SDK中工具链的g++可执行文件,例如/opt/t113-sdk/gcc-linaro-6.3.1/bin/arm-linux-gnueabihf-g++。
    • 同样方法添加C编译器,指向arm-linux-gnueabihf-gcc。
  2. 配置Qt版本:

    • 进入Qt版本标签页,点击“添加”。
    • 浏览到SDK中预编译好的qmake工具。这个qmake是专门为ARM架构生成的,路径可能像/opt/t113-sdk/qt5.12.8/bin/qmake。
    • 添加后,Qt Creator会自动检测出该Qt版本的名称和路径。
  3. 配置构建套件(Kit):

    • 进入Kits标签页,点击“添加”。
    • 给套件起个名字,如 “T113-ARM”。
    • “设备类型”选择“通用Linux设备”。
    • “编译器”选择刚才配置的ARM版GCC。
    • “Qt版本”选择刚才配置的ARM版Qt。
    • “调试器”可能需要手动指定SDK中的gdb,如arm-linux-gnueabihf-gdb。如果暂时不用调试,可以先不设。

注意:很多新手在这里会卡住,因为Qt Creator可能会报错说找不到有效的Qt版本。这通常是因为预编译的Qt库路径没有正确设置环境变量,或者qmake本身依赖的库在宿主机上不存在。一个排查方法是,在终端中手动运行一下那个ARM版的qmake -v,看它能否正确输出版本信息。如果报错缺少库,可能需要根据错误信息,在宿主机上安装对应的i386或兼容库。另一个常见坑是工具链的位数(32位/64位)与宿主机不匹配。

3.3 为交叉编译修改项目配置文件 (.pro)

Qt项目使用.pro文件来管理构建配置。为了让我们的程序能正确链接到板子上的库,并指定部署路径,需要在.pro文件中添加一些配置。

# HelloEmbeddedQt.pro QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = HelloEmbeddedQt TEMPLATE = app SOURCES += main.cpp \ mainwindow.cpp HEADERS += mainwindow.h FORMS += mainwindow.ui # --- 交叉编译相关配置 --- # 指定目标平台为嵌入式Linux linux-arm-gnueabihf- { # 链接时指定库搜索路径,指向SDK中的ARM Qt库路径 QMAKE_LIBDIR += /opt/t113-sdk/qt5.12.8/lib # 告诉编译器我们是在为ARM编译 QMAKE_CC = arm-linux-gnueabihf-gcc QMAKE_CXX = arm-linux-gnueabihf-g++ # 指定部署到板子上的路径(通过Qt Creator的部署步骤使用) target.path = /home/root/apps INSTALLS += target }

这段配置的意思是:当使用名为linux-arm-gnueabihf-的构建套件时(这个名字是在Kit配置里定义的),应用这些特定的编译器和路径规则。target.path定义了程序最终在板子上的存放目录。

3.4 构建、部署与运行

  1. 构建:在Qt Creator左下角,将构建套件切换到我们刚配置好的“T113-ARM”,然后点击“构建”按钮。构建输出目录会生成ARM架构的可执行文件HelloEmbeddedQt。你可以用file命令验证:file HelloEmbeddedQt,输出应包含“ARM”和“ELF 32-bit LSB executable”字样。

  2. 部署:Qt Creator支持自动部署。我们需要先配置一个“通用Linux设备”。在项目->运行设置中,添加一个新设备,类型选“通用Linux设备”。配置板子的IP地址、用户名(如root)、密码,以及认证方式(通常用密码或密钥)。然后,在“部署”步骤中,添加“上传文件”,将本地构建好的可执行文件上传到板子的target.path(如/home/root/apps)。同时,必须将程序运行所依赖的Qt库文件也上传到板子。最简单的方法是,将SDK中qt5.12.8/lib目录下相关的.so库文件(可以通过ldd命令在宿主机上查看程序依赖)拷贝到板子的/usr/lib或程序同级目录的lib文件夹下。这是最容易出错的一步,库缺失或版本不匹配会导致程序无法启动。

  3. 在板子上运行:

    • 通过串口或SSH登录开发板。
    • 进入程序所在目录:cd /home/root/apps
    • 设置显示环境变量并运行:
      # 如果使用framebuffer export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0 # 如果使用EGLFS(有GPU加速) # export QT_QPA_PLATFORM=eglfs # 指定插件路径,如果Qt库不在系统默认路径 export QT_PLUGIN_PATH=/usr/lib/qt/plugins export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH ./HelloEmbeddedQt -qws & # Qt4时代常用-qws,Qt5通常不需要,具体看平台插件
      对于Qt5,通常直接./HelloEmbeddedQt即可,平台插件会自动选择。当屏幕上出现你设计的窗口,并且按钮点击能正常响应时,恭喜你,第一个嵌入式Qt程序成功跑起来了!

4. 深度解析:嵌入式Qt的图形后端与平台插件

4.1 理解Qt Platform Abstraction (QPA)

为什么在桌面上运行./HelloEmbeddedQt就能弹出窗口,而在开发板上需要设置QT_QPA_PLATFORM环境变量?这背后是Qt的平台抽象层(QPA)。QPA是Qt用于处理底层窗口系统、输入设备和图形的抽象接口。在桌面Linux上,Qt默认使用xcb插件与X Window系统交互。而在没有X Server的嵌入式环境,我们需要使用其他插件。

  • linuxfb:直接向Linux Framebuffer (/dev/fb0) 绘制像素,纯软件渲染,兼容性最好,但性能较低,无硬件加速。
  • eglfs:基于EGL和OpenGL ES,直接使用GPU进行渲染,性能高,支持复杂动画和3D。但需要板子的GPU驱动支持EGL/GLES。
  • wayland:使用Wayland显示服务器协议,是现代Linux桌面和嵌入式系统的趋势,提供更好的合成和安全特性。

选择哪个插件,取决于板子的硬件能力和系统配置。通过export QT_QPA_PLATFORM=linuxfb来指定。你可以尝试不同的插件,观察程序启动日志(添加-platform verbose参数)来查看是否初始化成功。

4.2 处理输入设备:触摸屏与键盘

在嵌入式设备上,输入设备通常不是标准的USB鼠标键盘。可能是电阻/电容触摸屏,或者通过串口、GPIO连接的按键。

  • 触摸屏:对于Linux内核标准输入事件(/dev/input/eventX),Qt的evdev插件会自动处理。确保板子上有/dev/input/eventX设备节点(对应触摸屏),并且Qt编译时包含了-qtlibinfra -evdev支持。运行时,可以通过QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS环境变量微调。
  • 自定义键盘/按键:如果按键是通过GPIO或ADC读取的,通常需要自己写一个守护进程,将按键事件模拟成标准的输入事件(使用uinput内核模块),或者更直接地,在Qt应用中开启一个线程轮询GPIO状态,然后发送自定义的键盘事件(QKeyEvent)。

实操心得:触摸屏校准是个麻烦事。如果发现触摸坐标不准,可以使用ts_calibrate(t-slts库)工具进行校准,生成/etc/pointercal文件。Qt的evdev插件会读取这个文件。另外,注意触摸屏的输入事件可能和鼠标事件冲突,如果不需要鼠标,可以在运行程序时禁用鼠标插件:export QT_QPA_EGLFS_HIDECURSOR=1或export QT_QPA_FB_HIDECURSOR=1。

5. 程序优化与问题排查实战记录

5.1 缩减可执行文件与库的体积

直接编译出来的Qt程序,动态链接的话依赖一大堆.so文件,静态链接则单个文件巨大。对于存储空间紧张的板子,需要精简。

  1. 编译选项优化:在.pro文件中添加编译优化和尺寸优化选项。

    # 释放模式,优化尺寸和速度 CONFIG += release # 去除调试信息 QMAKE_CFLAGS_RELEASE += -Os QMAKE_CXXFLAGS_RELEASE += -Os # 静态链接C++标准库(谨慎使用,可能引发许可证问题) # QMAKE_LFLAGS += -static-libstdc++
  2. 裁剪Qt模块:在交叉编译Qt源码时(如果你选择自己编译),可以通过configure脚本的-skip参数跳过不需要的模块,如-skip qtwebengine -skip qt3d。对于使用预编译库的情况,我们只能通过不链接未使用的模块来间接“裁剪”,但库文件本身依然在文件系统中。

  3. 使用linuxdeployqt或手动整理依赖:在宿主机上,使用ldd命令查看可执行文件的依赖,只拷贝必要的.so文件到板子。更专业的工具是linuxdeployqt,它可以自动拷贝所有依赖库到指定目录,形成相对独立的发布包。

5.2 常见启动失败问题与排查技巧

程序在板子上跑不起来,是嵌入式开发的家常便饭。下面是一个速查表:

现象可能原因排查命令/方法
-bash: ./HelloEmbeddedQt: No such file or directory1. 文件确实不存在。
2. 文件存在,但架构不匹配(非ARM)。
3. 缺少动态链接器。
1.ls -l确认文件。
2.file HelloEmbeddedQt看架构。
3.readelf -l HelloEmbeddedQt | grep interpreter看动态链接器路径,检查板子上是否存在该文件(如/lib/ld-linux-armhf.so.3)。
./HelloEmbeddedQt: error while loading shared libraries: libQt5Core.so.5: cannot open shared object file缺少Qt库,或库路径不对。1.ldd HelloEmbeddedQt在宿主机查看所有依赖。
2. 在板子上echo $LD_LIBRARY_PATH检查库路径。
3. 将缺失的库从SDK拷贝到板子的/usr/lib或LD_LIBRARY_PATH包含的目录。
程序启动后黑屏或无显示1. 平台插件选择错误。
2. Framebuffer设备权限问题。
3. 显示驱动未加载。
1. 尝试不同QT_QPA_PLATFORM。
2.ls -l /dev/fb0查看权限,确保用户有读写权。
3.dmesg | grep -i drm|gpu查看GPU驱动加载日志。
触摸屏无反应1. 输入设备节点不对。
2.evdev插件未编译或未加载。
3. 触摸屏未校准。
1.cat /proc/bus/input/devices查看输入设备。
2. 检查Qt编译时是否包含evdev支持。
3. 运行ts_calibrate校准。
程序运行缓慢,界面卡顿1. 使用了性能较差的linuxfb插件。
2. CPU负载过高。
3. 未启用GPU硬件加速。
1. 尝试切换到eglfs插件(需硬件支持)。
2. 在板子上用top命令查看CPU使用率。
3. 检查/dev/dri/目录是否存在,以及libGLESv2.so等库是否就位。

一个真实的排查案例:我的程序在板子上启动时报错 “Failed to load platform plugin ‘eglfs’”。首先,我检查了LD_LIBRARY_PATH和库文件,都是对的。然后,我用strace命令跟踪程序启动:strace ./HelloEmbeddedQt 2>&1 | grep -i open。发现它在尝试打开/usr/lib/qt5/plugins/platforms/libqeglfs.so时失败了,原因是文件不存在。原来,SDK提供的库安装路径是/usr/lib/qt/plugins,而程序默认查找路径不同。解决方法有两个:一是创建软链接;二是在运行程序前设置export QT_PLUGIN_PATH=/usr/lib/qt/plugins。我选择了第二种。

5.3 进阶:使用CMake构建系统

现代Qt项目越来越多地使用CMake。交叉编译的配置思路与qmake类似,但写在CMakeLists.txt中。

cmake_minimum_required(VERSION 3.16) project(HelloEmbeddedQt LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 查找宿主机的Qt(用于设计阶段) find_package(Qt5 COMPONENTS Widgets REQUIRED) # 添加可执行文件 add_executable(HelloEmbeddedQt main.cpp mainwindow.cpp) target_link_libraries(HelloEmbeddedQt Qt5::Widgets) # --- 交叉编译配置,通过工具链文件(toolchain.cmake)引入更优雅 --- # 可以在这里设置交叉编译器、sysroot等变量 # set(CMAKE_SYSROOT /opt/t113-sdk/sysroot) # set(CMAKE_C_COMPILER /opt/t113-sdk/gcc-linaro-6.3.1/bin/arm-linux-gnueabihf-gcc)

创建一个独立的toolchain.cmake文件来封装所有交叉编译设置,然后在配置项目时通过-DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake参数指定,这样可以使主CMakeLists.txt保持干净,便于桌面和交叉编译的切换。

从在Qt Creator里拖出第一个按钮,到在粗糙的开发板屏幕上看到它亮起并响应点击,这个过程打通的不只是一个程序,更是对整个嵌入式Linux应用开发链条的理解。工具链、库依赖、平台插件、部署调试,每一个环节都可能成为拦路虎,但每一个问题的解决,都让这个链条在你脑中更加清晰。对于想深入的朋友,下一步可以研究如何将Qt程序集成到Yocto或Buildroot构建的根文件系统中,实现开机自启动;或者探索Qt Quick技术,用QML语言为嵌入式设备打造更炫酷、更流畅的现代UI。嵌入式Qt的世界很大,这第一个窗口,只是推开了那扇门。

相关新闻

  • Linux系统libcrypto.so.10缺失:OpenSSL 1.0.2k源码编译与兼容性解决方案
  • AI如何革新学术写作:智能助手的技术架构与应用
  • WinSock C++网络编程实战:从TCP/UDP基础到高性能服务器开发

最新新闻

  • 行空板OpenCV边缘检测实战:从环境部署到Canny算法调优
  • 回溯算法:原理、应用与优化策略
  • 2026年7月河北省保定市联通融合宽带办理全流程避坑攻略 - 找卡家园
  • 51单片机入门指南:从最小系统到串口通信的嵌入式开发实践
  • 终极指南:如何免费解锁Wand专业版功能并享受远程控制体验
  • Java线程创建与优化策略详解

日新闻

  • 金融舆情监测系统:多语言情感分析与实时可视化技术解析
  • QT C++调用Python异常处理:PyBind11实战与跨语言编程指南
  • A-47双麦回音消除模块:主次麦空间分布与差分连接对ENC性能的影响

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号