一、Qt 平台插件:QT_QPA_PLATFORM
QT_QPA_PLATFORM 用于选择 Qt 的 QPA(Qt Platform Abstraction)平台插件。
ini
export QT_QPA_PLATFORM=xcb
常见平台:
| 值 | 作用 |
|---|---|
xcb |
X11 |
wayland |
Wayland |
eglfs |
无 X11/Wayland 的嵌入式 EGLFS |
linuxfb |
Linux framebuffer |
也可以不用环境变量,直接:
bash
./app -platform eglfs
Qt 5.15 官方说明,嵌入式 Linux 可使用 EGLFS、LinuxFB、Wayland 等平台插件;具体是否可用取决于 Qt 的构建配置。
二、EGLFS / KMS
1. QT_QPA_EGLFS_INTEGRATION
指定 EGLFS 的设备集成 backend。
ini
export QT_QPA_EGLFS_INTEGRATION=eglfs_kms
对于 DRM/GBM 平台:
ini
QT_QPA_PLATFORM=eglfs
↓
eglfs_kms
↓
GBM
↓
DRM/KMS
Qt 5.15 官方明确说明,设置为 eglfs_kms 时使用 KMS/DRM backend。
注意:Qt 官方建议只有在确实需要强制指定 backend 时才设置它;设备本身可能已经通过 Qt 构建配置指定了默认 backend。
2. QT_QPA_EGLFS_KMS_CONFIG
指定 eglfs_kms 的 JSON 配置文件。
javascript
export QT_QPA_EGLFS_KMS_CONFIG=/path/to/kms.json
例如:
json
{
"device": "/dev/dri/card0",
"outputs": [
{
"name": "HDMI1",
"mode": "1920x1080"
},
{
"name": "DSI1",
"mode": "1024x600"
}
]
}
Qt 官方支持通过该配置指定 DRM 设备、输出、分辨率、virtual desktop 顺序等。多个 active output 对应多个 QScreen。
3. QT_QPA_EGLFS_PHYSICAL_WIDTH / QT_QPA_EGLFS_PHYSICAL_HEIGHT
指定屏幕物理尺寸,单位 mm。
ini
export QT_QPA_EGLFS_PHYSICAL_WIDTH=520
export QT_QPA_EGLFS_PHYSICAL_HEIGHT=290
当 Qt 无法自动获得物理尺寸时使用。
Qt 5.15 文档指出,这些值会影响 DPI;对 Qt Widgets 和 Qt Quick Controls 等依赖 DPI 的界面尤其重要。多屏情况下,建议在 KMS JSON 的 outputs 中为每个输出单独指定 physicalWidth / physicalHeight。
4. QT_QPA_EGLFS_WIDTH / QT_QPA_EGLFS_HEIGHT
手动指定屏幕分辨率:
ini
export QT_QPA_EGLFS_WIDTH=1920
export QT_QPA_EGLFS_HEIGHT=1080
Qt 5.15 说明:EGLFS 会尝试自动获取屏幕尺寸,但某些平台可能无法正确获取,此时可以手动指定。
对于 eglfs_kms 多屏场景,优先使用 KMS 输出配置,不建议把这两个变量当成双屏配置手段。
5. QT_QPA_EGLFS_FB
指定 framebuffer 设备:
javascript
export QT_QPA_EGLFS_FB=/dev/fb0
默认值为:
bash
/dev/fb0
Qt 5.15 特别说明:在多数嵌入式平台中,这个变量对于 KMS/DRM backend 并不重要,因为 framebuffer 主要用于查询显示参数;某些平台才会用它选择显示设备。
因此在 RK3588 的 eglfs_kms 场景中,通常不需要配置它。
6. QT_QPA_EGLFS_FORCE888
强制 EGL 配置使用每个 RGB 通道 8 bit:
ini
export QT_QPA_EGLFS_FORCE888=1
主要用于某些平台默认选择 RGB565、RGB444 等较低位深配置,而应用希望使用 24/32 bpp 配置的情况。
7. QT_QPA_EGLFS_SWAPINTERVAL
控制 EGL swap interval。
默认:
1
通常意味着同步显示刷新。
例如:
ini
export QT_QPA_EGLFS_SWAPINTERVAL=0
用于测试关闭 swap 阻塞。
Qt 5.15 官方说明,默认请求 swap interval 为 1;设置为 0 可以关闭由 swap 带来的同步阻塞。
三、EGLFS 调试
QT_QPA_EGLFS_DEBUG
开启 EGLFS 调试信息:
ini
export QT_QPA_EGLFS_DEBUG=1
可看到 EGL 配置、surface/context 等相关信息。
Qt 5.15 官方同时提供几个非常有用的日志类别:
ini
export QT_LOGGING_RULES="qt.qpa.egldeviceintegration=true"
查看 EGLFS device integration。
ini
export QT_LOGGING_RULES="qt.qpa.eglfs.kms=true"
查看 KMS/DRM backend。
ini
export QT_LOGGING_RULES="qt.qpa.input=true"
查看输入设备。
也可以一次打开:
ini
export QT_LOGGING_RULES="qt.qpa.*=true"
Qt 官方明确列出了 qt.qpa.egldeviceintegration、qt.qpa.input 和 qt.qpa.eglfs.kms 这些类别。
四、Qt Quick 渲染
QSG_RENDER_LOOP
控制 Qt Quick Scene Graph render loop。
常用:
ini
export QSG_RENDER_LOOP=threaded
或者:
ini
export QSG_RENDER_LOOP=basic
含义:
| 值 | 含义 |
|---|---|
threaded |
渲染线程与 GUI 线程分离 |
basic |
基本的单线程渲染 |
对于 Qt 5.15 + EGLFS/KMS 多屏场景,这个变量尤其值得注意。
Qt 官方明确说明:EGLFS 下 Qt Quick 默认使用 threaded render loop;多屏时每个 QQuickWindow/QQuickView 可以拥有自己的 render thread,从而根据各自的 vsync 独立节流。官方同时指出,使用 basic loop 时,多屏场景可能导致动画等行为出现问题。
所以双屏 Qt Quick 项目通常保持:
bash
unset QSG_RENDER_LOOP
让 Qt 使用默认值即可;调试线程问题时再显式设置。
QSG_INFO
查看 Qt Quick Scene Graph 信息:
ini
export QSG_INFO=1
和:
ini
export QT_QPA_EGLFS_DEBUG=1
结合使用,可以帮助判断 Qt Quick 实际的图形配置。
Qt 官方 EGLFS 文档明确建议将 EGLFS debug 与 QSG_INFO 配合使用来排查 EGL 配置问题。
五、Qt 插件调试
QT_DEBUG_PLUGINS
查看 Qt 动态插件加载过程:
ini
export QT_DEBUG_PLUGINS=1
例如排查:
xcb plugin 加载失败
eglfs plugin 加载失败
wayland plugin 加载失败
platform plugin 找不到
Qt 官方将该变量用于输出插件加载诊断信息。
六、Qt 日志
QT_LOGGING_RULES
统一控制 Qt logging categories。
例如:
ini
export QT_LOGGING_RULES="qt.qpa.*=true"
EGLFS/KMS:
ini
export QT_LOGGING_RULES="qt.qpa.eglfs.kms=true"
同时打开多个类别:
ini
export QT_LOGGING_RULES="qt.qpa.egldeviceintegration=true;qt.qpa.eglfs.kms=true"
这比盲目打开所有 Qt 日志更适合实际排障。
七、运行环境相关
DISPLAY
X11 使用:
ini
export DISPLAY=:0
表示 X Server。
如果:
Qt → xcb
这个变量通常由桌面环境自动提供。
WAYLAND_DISPLAY
Wayland 客户端用于找到 Wayland socket,例如:
ini
export WAYLAND_DISPLAY=wayland-0
通常不需要手工设置,由 Wayland session 环境提供。
XDG_RUNTIME_DIR
Wayland 等 Linux 用户级运行时环境使用的目录。
例如:
bash
echo $XDG_RUNTIME_DIR
常见:
arduino
/run/user/1000
需要注意:
它不是 Qt 所有 Linux 程序都必须设置的变量。
它主要与 Wayland、用户级 runtime socket 等环境有关;不要为了运行 xcb 或 eglfs_kms 就无条件手动设置:
ini
XDG_RUNTIME_DIR=/tmp/runtime-root
八、Qt 运行库与 QML 路径
LD_LIBRARY_PATH
用于动态库搜索:
bash
export LD_LIBRARY_PATH=/opt/qt/lib:$LD_LIBRARY_PATH
如果 Qt 已经正确安装并设置了 RPATH,通常不需要额外设置。
QT_PLUGIN_PATH
指定 Qt 插件搜索路径:
javascript
export QT_PLUGIN_PATH=/opt/qt/plugins
用于插件部署或自定义 Qt 安装目录。
QT_QPA_PLATFORM_PLUGIN_PATH
指定 QPA platform plugin 所在目录:
javascript
export QT_QPA_PLATFORM_PLUGIN_PATH=/opt/qt/plugins/platforms
适合排查:
arduino
Could not find the Qt platform plugin
等问题。
QML2_IMPORT_PATH
指定 QML 模块搜索路径:
javascript
export QML2_IMPORT_PATH=/opt/qt/qml
主要用于 Qt Quick/QML 模块部署。
Qt 官方 Linux 调试资料也将 LD_LIBRARY_PATH、QT_QPA_PLATFORM、QT_QPA_PLATFORM_PLUGIN_PATH 和 QML2_IMPORT_PATH 列为常见 Linux Qt 运行环境变量。
九、RK3588 项目实际使用
1. Ubuntu + X11 开发
bash
export QT_QPA_PLATFORM=xcb
./media_app
显示链路:
Qt Quick
↓
xcb
↓
Xorg
↓
HDMI + DSI
双屏窗口采用 X11 的窗口 geometry 管理。
2. RK3588 EGLFS/KMS 实机测试
首先确保 Xorg/Wayland compositor 没有占用显示设备,然后:
ini
export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_INTEGRATION=eglfs_kms
export QT_QPA_EGLFS_KMS_CONFIG=/path/to/kms.json
./media_app
显示链路:
Qt Quick
↓
EGLFS
↓
eglfs_kms
↓
GBM
↓
DRM/KMS
├── HDMI
└── DSI
eglfs_kms 会把 active outputs 报告为 QScreen,多屏应用可以给不同 QQuickView/QQuickWindow 调用:
scss
view->setScreen(screen);
view->showFullScreen();
Qt 官方明确建议每块屏幕使用独立的 QQuickView/QQuickWindow,并在 show() 前完成 setScreen()。
十、常用排障组合
查看当前平台
ini
QT_DEBUG_PLUGINS=1 \
./media_app -platform eglfs
查看 EGLFS backend
ini
QT_QPA_EGLFS_DEBUG=1 \
QT_LOGGING_RULES="qt.qpa.egldeviceintegration=true" \
./media_app -platform eglfs
查看 KMS/DRM
ini
QT_QPA_EGLFS_DEBUG=1 \
QT_LOGGING_RULES="qt.qpa.eglfs.kms=true" \
./media_app -platform eglfs
EGLFS 双屏完整调试
ini
QT_QPA_PLATFORM=eglfs \
QT_QPA_EGLFS_INTEGRATION=eglfs_kms \
QT_QPA_EGLFS_KMS_CONFIG=/path/to/kms.json \
QT_QPA_EGLFS_DEBUG=1 \
QT_LOGGING_RULES="qt.qpa.egldeviceintegration=true;qt.qpa.eglfs.kms=true" \
./media_app
十一、最终速查表
| 变量 | 主要用途 | RK3588 项目 |
|---|---|---|
QT_QPA_PLATFORM |
选择 QPA 平台 | 常用 |
QT_QPA_EGLFS_INTEGRATION |
选择 EGLFS backend | KMS 时常用 |
QT_QPA_EGLFS_KMS_CONFIG |
KMS 多屏配置 | 双屏常用 |
QT_QPA_EGLFS_PHYSICAL_WIDTH/HEIGHT |
物理尺寸/DPI | 按需 |
QT_QPA_EGLFS_WIDTH/HEIGHT |
EGLFS 屏幕尺寸 | 按需 |
QT_QPA_EGLFS_FB |
framebuffer 设备 | KMS 通常不用 |
QT_QPA_EGLFS_FORCE888 |
强制 RGB888 | 排障时使用 |
QT_QPA_EGLFS_SWAPINTERVAL |
swap/vsync | 性能测试 |
QT_QPA_EGLFS_DEBUG |
EGLFS 调试 | 排障常用 |
QSG_RENDER_LOOP |
Qt Quick 渲染循环 | 排障/调优 |
QSG_INFO |
Scene Graph 信息 | 排障常用 |
QT_LOGGING_RULES |
Qt 分类日志 | 排障常用 |
QT_DEBUG_PLUGINS |
插件加载日志 | 排障常用 |
DISPLAY |
X11 display | xcb |
WAYLAND_DISPLAY |
Wayland socket | Wayland |
XDG_RUNTIME_DIR |
用户 runtime 环境 | Wayland 等场景 |
LD_LIBRARY_PATH |
动态库路径 | 部署时按需 |
QT_PLUGIN_PATH |
Qt 插件路径 | 部署时按需 |
QT_QPA_PLATFORM_PLUGIN_PATH |
QPA 插件路径 | 部署/排障 |
QML2_IMPORT_PATH |
QML 模块路径 | QML 部署 |
十二、最值得记住的几组
X11
ini
QT_QPA_PLATFORM=xcb
Wayland
ini
QT_QPA_PLATFORM=wayland
RK3588 EGLFS/KMS
ini
QT_QPA_PLATFORM=eglfs
QT_QPA_EGLFS_INTEGRATION=eglfs_kms
QT_QPA_EGLFS_KMS_CONFIG=/path/to/kms.json
EGLFS 排障
ini
QT_QPA_EGLFS_DEBUG=1
QT_LOGGING_RULES="qt.qpa.egldeviceintegration=true;qt.qpa.eglfs.kms=true"
Qt Quick 排障
ini
QSG_INFO=1
QSG_RENDER_LOOP=threaded
其中 QSG_RENDER_LOOP=threaded 主要用于调试/验证,不建议没有问题时为了"性能"强行设置;Qt 官方在 EGLFS 下本身就以 threaded render loop 为默认推荐路径。
核心关系
markdown
QT_QPA_PLATFORM
│
├── xcb
│ └── X11
│
├── wayland
│ └── Wayland compositor
│
└── eglfs
└── QT_QPA_EGLFS_INTEGRATION
│
└── eglfs_kms
└── DRM/KMS
因此实际开发时首先确定的是:
"Qt 应该连接到哪个显示架构?"
然后再决定:
xcb / wayland / eglfs
进入 EGLFS 后,才需要进一步考虑:
scss
eglfs_kms
KMS JSON
QScreen
setScreen()
showFullScreen()
这也是 Qt 官方文档中 EGLFS、KMS/DRM 和多屏配置的基本关系。