Qt 做跨平台上位机,一套代码同时跑在 Windows 和 Linux 工控机上完全可行。真正要花心思的不是界面代码,而是串口权限、路径编码、字体渲染和部署打包这四个"边角",把它们理顺,双平台适配成本能压到最低。这篇按实际项目的推进顺序讲。
界面代码真能一行不改,两端通吃吗?
九成能。Qt Widgets 的布局体系本来就是跨平台设计的,Windows 上开发的界面搬到 Linux,顶多字体渲染略有差异。剩下的一成集中在系统调用:注册表读写、Windows 服务、特定 DLL,这些用条件编译隔离,Q_OS_WIN 和 Q_OS_LINUX 宏只允许出现在平台适配层,业务代码保持纯净。架构上管住这一条,跨平台上位机项目就成功了一半。
反过来讲,把 if(isWindows) 散落在业务代码各处的工程,后期的维护成本会指数级上升。这点很关键。
串口和网络通信,两端差异在哪?
Linux 下串口是设备文件,/dev/ttyUSB0 默认只有 root 和 dialout 组能访问,程序一打开就报"权限拒绝",这是新手必踩的第一坑——把运行用户加进 dialout 组,或者写条 udev 规则就解决了。串口参数用 QSerialPort 设置,两个平台写法一致,但个别 USB 转串口转换器上流控行为略有差别,现场联调要留心。USB 转串口芯片驱动方面,Windows 要装厂家驱动,Linux 内核大多自带 CH341、FTDI 驱动,插上就能识别,这点反而省心。
网络通信层完全一致,QTcpSocket、QUdpSocket 一套代码两端跑,设备数据采集的逻辑不用做任何改动。
路径、编码、配置文件怎么处理才不出幺蛾子?
三个习惯:路径一律用 QStandardPaths 拿标准目录,别写死 C 盘;文件拼接交给 QDir,分隔符的事让 Qt 处理;编码上 Linux 默认 UTF-8,而工控现场不少老数据文件是 GBK,读取时用 QStringDecoder 显式指定,界面上中文乱码十有八九是编码没对齐。配置文件统一 ini 或 JSON,存在用户目录下,两个平台行为完全一致。
部署打包,哪一步最容易翻车?
Windows 端 windeployqt 一把梭,基本没问题。Linux 端麻烦些:linuxdeployqt 打完包,目标机器缺 libGL、fontconfig 是常事,最稳的办法是用 Docker 起一个和现场同版本的干净环境做验证。字体也得随包带上,工控机的 Linux 多数没装中文字体,界面全是方框。开机自启用 systemd 服务,再配个看门狗,进程崩了十秒内自动拉起——产线环境里,这一点必须有。
我之前接手一个苏州上位机系统开发的改造项目,客户车间新采购的工控机预装 Linux,老系统是 Windows 版。我们给 Qt 工程加了一套 CMake 双平台构建,前后一周完成迁移,现场三个月零维护。实时曲线、设备数据采集这些业务代码,一行没动。
新项目想跨平台,第一步做什么?
行动建议:如果新项目确定要跨平台,第一周就把双平台 CI 构建跑通,之后每周自动出一次 Windows 和 Linux 安装包。适配问题攒到最后集中处理是灾难,每周小步验证才是顺的路。