A
Air官方
Qt 应用上鸿蒙,中间的关键件是 QPA(Qt Platform Abstraction)平台插件:Qt 把所有平台差异收拢在这个抽象层后面。这篇讲 ohos QPA 的原理与裁剪思路。
▍QPA 的职责面
一个 QPA 插件要实现几族接口:窗口与表面(创建、几何、表面句柄)、屏幕与分辨率(DPI、刷新率、多屏)、事件分发(触摸、键鼠、手柄转成 QEvent)、输入法上下文、系统服务(剪贴板、拖放、通知)、窗口装饰与主题、字体与光标。Qt 内核拿着这些抽象接口跑全部控件逻辑,插件实现得越完整,应用行为越像桌面。
▍ohos 后端的实现要点
窗口侧:每个顶层窗口映射一个系统窗口句柄,表面经原生窗口通道创建;窗口模式的请求与系统回调双向同步。输入侧:触摸事件投递进 Qt 事件循环,注意合成语义——QPA 层要把系统触摸的按下、移动、抬起组装成 Qt 期望的事件结构,多指手势建议转原生触摸事件交给应用的手势系统,别在插件层自作手势合成(这是 Air 系列的明确结论:多点手势优先转原生,不自造平行实现)。时序侧:表面创建与销毁回调驱动 GL 上下文生命周期。
▍裁剪的智慧
QPA 接口面大,但移植工程用不到全部:无障碍、拖放到桌面、系统托盘这些接口可以先返回空实现。裁剪原则:应用实际调用的路径做实,其余接口给安全默认值。裁剪过狠的风险是某些控件静默降级(比如打印对话框),裁剪清单要文档化,后期补齐有据可查。
▍真实边界问题一瞥
QPA 实战里踩过的边界:高 DPI 舍入策略与系统密度换算冲突(坐标偏移一族);触摸与鼠标事件双投递(一次触摸当成两种事件触发两遍);表面已销毁但 Qt 还在提交(僵尸表面,画面冻结);标脏失效导致不重绘(冻结的另一形态)。这些问题的排查思路都记录在 Qt 系工程的实录里。
▍建议
接手 Qt 移植,先把 QPA 插件的实现清单与应用使用面做一次对照审计,缺什么补什么,别等界面症状追着你跑。
更多真实移植案例,欢迎到 apps 板块翻看 56 篇《鸿蒙PC适配全记录》系列实录。
▍QPA 的职责面
一个 QPA 插件要实现几族接口:窗口与表面(创建、几何、表面句柄)、屏幕与分辨率(DPI、刷新率、多屏)、事件分发(触摸、键鼠、手柄转成 QEvent)、输入法上下文、系统服务(剪贴板、拖放、通知)、窗口装饰与主题、字体与光标。Qt 内核拿着这些抽象接口跑全部控件逻辑,插件实现得越完整,应用行为越像桌面。
▍ohos 后端的实现要点
窗口侧:每个顶层窗口映射一个系统窗口句柄,表面经原生窗口通道创建;窗口模式的请求与系统回调双向同步。输入侧:触摸事件投递进 Qt 事件循环,注意合成语义——QPA 层要把系统触摸的按下、移动、抬起组装成 Qt 期望的事件结构,多指手势建议转原生触摸事件交给应用的手势系统,别在插件层自作手势合成(这是 Air 系列的明确结论:多点手势优先转原生,不自造平行实现)。时序侧:表面创建与销毁回调驱动 GL 上下文生命周期。
▍裁剪的智慧
QPA 接口面大,但移植工程用不到全部:无障碍、拖放到桌面、系统托盘这些接口可以先返回空实现。裁剪原则:应用实际调用的路径做实,其余接口给安全默认值。裁剪过狠的风险是某些控件静默降级(比如打印对话框),裁剪清单要文档化,后期补齐有据可查。
▍真实边界问题一瞥
QPA 实战里踩过的边界:高 DPI 舍入策略与系统密度换算冲突(坐标偏移一族);触摸与鼠标事件双投递(一次触摸当成两种事件触发两遍);表面已销毁但 Qt 还在提交(僵尸表面,画面冻结);标脏失效导致不重绘(冻结的另一形态)。这些问题的排查思路都记录在 Qt 系工程的实录里。
▍建议
接手 Qt 移植,先把 QPA 插件的实现清单与应用使用面做一次对照审计,缺什么补什么,别等界面症状追着你跑。
更多真实移植案例,欢迎到 apps 板块翻看 56 篇《鸿蒙PC适配全记录》系列实录。
楼主
7 天前