Buildroot开发板Qt字体安装与显示统一教程
Buildroot 开发板安装字体并统一 Qt 显示效果教程1. 问题背景在 OK3506 Buildroot 开发板上运行 Qt 程序时虽然已经通过下面方式解决了横屏显示问题exportQT_QPA_FB_DRM1exportQT_QPA_PLATFORMlinuxfb:rotation90./New_Jydl但是仍然可能出现一个新问题开发板 Qt 程序的显示效果和 Ubuntu 虚拟机 Qt 程序显示效果不一致。常见表现包括字体大小不一致 字体粗细不一致 中文显示效果不一致 按钮中文字位置不一致 表格行高不一致 界面控件间距不一致造成这个问题的重要原因之一就是Ubuntu 虚拟机和 Buildroot 开发板使用的字体不一致。因此需要把 Ubuntu 上用于 Qt 程序显示的字体复制到 Buildroot 开发板并让 Qt 程序使用同一套字体。2. 当前开发板字体包开发板/root目录下已有两个字体相关压缩包program_fonts.tar.gz program_fonts_2.tar.gz查看文件ls可以看到类似FaultReport New_Jydl lib lib_json.tgz libhiredis.a libhiredis.so libhiredis.so.1.3.0 program_fonts.tar.gz program_fonts_2.tar.gz start.sh ui_source3. 查看字体包内容3.1 查看program_fonts.tar.gz执行tar-tzfprogram_fonts.tar.gz输出ui_source/program_fonts/ ui_source/program_fonts/NotoMono-Regular.ttf ui_source/program_fonts/Ubuntu-M.ttf ui_source/program_fonts/Ubuntu-C.ttf ui_source/program_fonts/Ubuntu-R.ttf ui_source/program_fonts/NotoSansCJK-Bold.ttc ui_source/program_fonts/DejaVuSans-Bold.ttf ui_source/program_fonts/NotoSansCJK-Regular.ttc ui_source/program_fonts/FreeSerif.ttf ui_source/program_fonts/FONT_MANIFEST.txt ui_source/program_fonts/ukai.ttc ui_source/program_fonts/wqy-zenhei.ttc ui_source/program_fonts/DejaVuSans.ttf说明这个包里主要是字体文件包括NotoSansCJK-Regular.ttc NotoSansCJK-Bold.ttc Ubuntu-R.ttf Ubuntu-M.ttf Ubuntu-C.ttf DejaVuSans.ttf DejaVuSans-Bold.ttf wqy-zenhei.ttc ukai.ttc这些字体里比较推荐 Qt 中文界面使用NotoSansCJK-Regular.ttc NotoSansCJK-Bold.ttc3.2 查看program_fonts_2.tar.gz执行tar-tzfprogram_fonts_2.tar.gz输出69-jypmc11-cn-font-alias.conf说明这个包里是 fontconfig 字体别名配置文件。它的作用一般是给中文字体设置别名让系统或 Qt 更容易匹配到合适的中文字体。4. BusyBox tar 注意事项在 Buildroot 开发板上tar通常是 BusyBox 版本。执行错误命令tar-rzfprogram_fonts.tar.gz-C/home/forlinx/.config/fontconfig/conf.d69-jypmc11-cn-font-alias.conf可能会报错tar: invalid option -- r BusyBox v1.36.1 ...原因是1. BusyBox tar 不支持 -r 追加参数 2. .tar.gz 是 gzip 压缩包本来也不适合直接追加文件所以在开发板上不要使用tar-rzfxxx.tar.gz...正确思路是解压压缩包 复制字体文件到 /usr/share/fonts/ 复制 .conf 配置文件到 /etc/fonts/conf.d/5. 推荐安装目录建议把项目字体单独放到/usr/share/fonts/jypmc11fontconfig 配置文件放到/etc/fonts/conf.d这样目录清晰方便后续维护。6. 一键安装字体命令在开发板上执行下面命令rm-rf/tmp/program_fontsmkdir-p/tmp/program_fontstar-xzf/root/program_fonts.tar.gz-C/tmp/program_fontstar-xzf/root/program_fonts_2.tar.gz-C/tmp/program_fontsmkdir-p/usr/share/fonts/jypmc11mkdir-p/etc/fonts/conf.dfind/tmp/program_fonts-typef|grep-E\.ttf$|\.ttc$|\.otf$|whilereadfdocp$f/usr/share/fonts/jypmc11/donefind/tmp/program_fonts-typef|grep\.conf$|whilereadfdocp$f/etc/fonts/conf.d/donesync这组命令完成的事情是1. 创建临时目录 /tmp/program_fonts 2. 解压两个字体包 3. 创建开发板字体目录 /usr/share/fonts/jypmc11 4. 创建 fontconfig 配置目录 /etc/fonts/conf.d 5. 复制 .ttf / .ttc / .otf 字体文件 6. 复制 .conf 字体配置文件 7. sync 保存到存储设备7. 检查字体是否安装成功执行ls-l/usr/share/fonts/jypmc11应该能看到类似DejaVuSans-Bold.ttf DejaVuSans.ttf FreeSerif.ttf NotoMono-Regular.ttf NotoSansCJK-Bold.ttc NotoSansCJK-Regular.ttc Ubuntu-C.ttf Ubuntu-M.ttf Ubuntu-R.ttf ukai.ttc wqy-zenhei.ttc检查 fontconfig 配置ls-l/etc/fonts/conf.d/|grepjypmc应该看到69-jypmc11-cn-font-alias.conf8. 刷新字体缓存如果开发板系统带有fontconfig可以执行whichfc-cachewhichfc-match如果能找到命令例如/usr/bin/fc-cache /usr/bin/fc-match则刷新字体缓存fc-cache-fv测试字体匹配fc-match fc-matchNoto Sans CJK SCfc-matchUbuntufc-matchWenQuanYi Zen Hei如果开发板没有fc-cache和fc-match也不是致命问题。因为 Qt 的嵌入式平台插件仍然可以通过下面环境变量查找字体exportQT_QPA_FONTDIR/usr/share/fonts9. Qt 启动脚本中指定字体目录开发板启动 Qt 程序时建议加入字体相关环境变量exportQT_QPA_FONTDIR/usr/share/fontsexportQT_FONT_DPI96exportQT_SCALE_FACTOR1完整启动示例unsetQT_DEBUG_PLUGINSunsetQT_QPA_EGLFS_ROTATIONunsetQT_QPA_EGLFS_INTEGRATIONexportQT_QPA_FB_DRM1exportQT_QPA_PLATFORMlinuxfb:rotation90exportQT_QPA_PLATFORM_PLUGIN_PATH/usr/lib/qt/pluginsexportQT_QPA_FONTDIR/usr/share/fontsexportQT_IM_MODULEqtvirtualkeyboardexportQT_FONT_DPI96exportQT_SCALE_FACTOR1cd/root ./New_Jydl关键环境变量说明环境变量作用QT_QPA_FB_DRM1让 Qt linuxfb 走 DRM 显示路径QT_QPA_PLATFORMlinuxfb:rotation90使用 linuxfb 平台并旋转 90 度QT_QPA_PLATFORM_PLUGIN_PATH/usr/lib/qt/plugins指定 Qt 插件目录QT_QPA_FONTDIR/usr/share/fonts指定 Qt 字体搜索目录QT_FONT_DPI96固定字体 DPIQT_SCALE_FACTOR1固定 Qt 缩放比例QT_IM_MODULEqtvirtualkeyboard启用 Qt 虚拟键盘输入法模块10. 开机自启脚本示例可以修改或创建vi/etc/init.d/S99New_Jydl写入#!/bin/shcase$1instart)echoStarting New_Jydl...unsetQT_DEBUG_PLUGINSunsetQT_QPA_EGLFS_ROTATIONunsetQT_QPA_EGLFS_INTEGRATIONexportQT_QPA_FB_DRM1exportQT_QPA_PLATFORMlinuxfb:rotation90exportQT_QPA_PLATFORM_PLUGIN_PATH/usr/lib/qt/pluginsexportQT_QPA_FONTDIR/usr/share/fontsexportQT_IM_MODULEqtvirtualkeyboardexportQT_FONT_DPI96exportQT_SCALE_FACTOR1cd/root ./New_Jydl;;stop)echoStopping New_Jydl...killallNew_Jydl;;restart)$0stopsleep1$0start;;*)echoUsage:$0{start|stop|restart}exit1;;esacexit0添加执行权限chmodx /etc/init.d/S99New_Jydlsyncreboot11. Qt 代码中固定字体只把字体复制到开发板还不够因为 Qt 可能仍然使用默认字体。建议在main.cpp中强制指定字体、样式和 DPI。参考代码#includeQApplication#includeQStyleFactory#includeQFont#includemainwindow.hintmain(intargc,char*argv[]){/* * 注意 * 这两个属性必须在 QApplication 创建之前设置。 */QApplication::setAttribute(Qt::AA_DisableHighDpiScaling);QApplication::setAttribute(Qt::AA_Use96Dpi);QApplicationapp(argc,argv);/* * 统一 Qt 控件样式减少 Ubuntu 和开发板显示差异。 */app.setStyle(QStyleFactory::create(Fusion));/* * 统一中文字体。 * 推荐使用 Noto Sans CJK SC。 */QFontfont(Noto Sans CJK SC);font.setPixelSize(18);app.setFont(font);MainWindow w;w.resize(1280,720);w.showFullScreen();returnapp.exec();}如果想使用 Ubuntu 字体也可以改成QFontfont(Ubuntu);font.setPixelSize(18);app.setFont(font);但是中文界面更推荐QFontfont(Noto Sans CJK SC);因为字体包里已经包含NotoSansCJK-Regular.ttc NotoSansCJK-Bold.ttc12. 为什么建议使用 setPixelSizeQt 字体有两种常见设置方式font.setPointSize(12);和font.setPixelSize(18);对于嵌入式 HMI 固定分辨率界面建议优先使用font.setPixelSize(18);原因是pointSize 会受 DPI 影响 pixelSize 更适合固定 1280x720 这类工业屏界面 pixelSize 在 Ubuntu 和开发板之间更容易保持一致如果程序要适配多种分辨率可以再设计一套统一缩放策略。13. Ubuntu 端也要统一设置Ubuntu 虚拟机运行 Qt 程序时也建议指定exportQT_FONT_DPI96exportQT_SCALE_FACTOR1./New_Jydl如果 Ubuntu 使用 xcb可以明确exportQT_QPA_PLATFORMxcbexportQT_FONT_DPI96exportQT_SCALE_FACTOR1./New_Jydl这样可以避免 Ubuntu 桌面缩放影响 Qt 程序显示效果。14. 常用排查命令14.1 开发板查看 Qt 环境变量env|grepQT重点检查QT_QPA_FB_DRM QT_QPA_PLATFORM QT_QPA_FONTDIR QT_FONT_DPI QT_SCALE_FACTOR14.2 查看 Qt 插件find/usr/lib/qt/plugins-maxdepth3-typef开发板当前主要平台插件libqlinuxfb.so libqminimal.so libqoffscreen.so libqvnc.so14.3 查看字体文件find/usr/share/fonts-typef或者只看项目字体目录ls-l/usr/share/fonts/jypmc1114.4 查看 fontconfig 配置ls-l/etc/fonts/conf.d/如果有fc-matchfc-matchNoto Sans CJK SC14.5 打开 Qt 插件调试临时调试exportQT_DEBUG_PLUGINS1./New_Jydl21|tee/tmp/qt_debug.log看是否加载了/usr/lib/qt/plugins/platforms/libqlinuxfb.so调试完建议关闭unsetQT_DEBUG_PLUGINS15. 字体安装后的最终运行方式推荐最终运行方式unsetQT_DEBUG_PLUGINSunsetQT_QPA_EGLFS_ROTATIONunsetQT_QPA_EGLFS_INTEGRATIONexportQT_QPA_FB_DRM1exportQT_QPA_PLATFORMlinuxfb:rotation90exportQT_QPA_PLATFORM_PLUGIN_PATH/usr/lib/qt/pluginsexportQT_QPA_FONTDIR/usr/share/fontsexportQT_IM_MODULEqtvirtualkeyboardexportQT_FONT_DPI96exportQT_SCALE_FACTOR1cd/root ./New_Jydl16. 总结本次字体安装的核心流程是1. program_fonts.tar.gz 中保存字体文件 2. program_fonts_2.tar.gz 中保存 fontconfig 配置文件 3. 字体文件复制到 /usr/share/fonts/jypmc11 4. 配置文件复制到 /etc/fonts/conf.d 5. 如果有 fontconfig执行 fc-cache -fv 6. Qt 启动时指定 QT_QPA_FONTDIR/usr/share/fonts 7. Qt 启动时固定 QT_FONT_DPI96 和 QT_SCALE_FACTOR1 8. Qt 代码中固定 Fusion 样式和 Noto Sans CJK SC 字体一句话总结要让 Ubuntu 虚拟机和 Buildroot 开发板上的 Qt 程序显示效果尽量一致必须让两边使用同一套字体、同一个 DPI、同一个缩放比例和同一个 Qt 样式。推荐最终组合字体Noto Sans CJK SC 样式Fusion 字号setPixelSize DPI96 缩放1 开发板字体目录/usr/share/fonts/jypmc11 Qt 字体搜索目录QT_QPA_FONTDIR/usr/share/fonts