当前位置: 首页 > news >正文

鸿蒙PC:Qt适配OpenHarmony实战【明算】:用 Qt Quick 做一个轻量四则运算计算器

前言欢迎加入鸿蒙PC开发者社区共同打造开发者工具生态鸿蒙PC开发者社区 https://harmonypc.csdn.net/项目开源地址https://AtomGit.com/lqjmac/qt_mingsuan这篇文章记录第 2 个 Qt 适配鸿蒙小项目明算。明算是一个轻量计算器它把数字输入、四则运算、退格、清空和错误提示集中在一个 Qt Quick 页面里。项目定位是简易计算器核心功能是加减乘除四则运算。本文会从工程结构、Qt SDK 配置、QML 界面、入口函数、窗口缩放验证、安装运行和常见问题几个角度完整拆解。为了便于继续扩展文章中的命令、路径和 Bundle Name 都按实际项目填写。提示本文不是只展示界面截图而是把一个可构建、可安装、可启动的 Qt for OpenHarmony 项目拆开讲清楚。一、项目定位与学习目标1.1 为什么选择这个项目计算器项目很适合验证按钮网格、文本状态、输入反馈和窗口缩放因为它的交互密度比时钟更高。从学习路径看明算的价值不在于功能复杂而在于它足够小适合集中验证 Qt Quick 在鸿蒙窗口里的运行方式。做这种小项目时我更关心三件事能不能构建、能不能显示、窗口变化时能不能立即刷新。这三件事都跑通以后再继续堆业务功能才比较踏实。1.2 本文会覆盖哪些知识点主要学习点如下数字输入加减乘除小数点处理正负号切换除零提示Qt SDK 使用相对路径配置main和qtmain双入口保留HAP 构建、安装、启动命令最大化和还原时的窗口刷新检查1.3 最终效果截图图 1明算在 OpenHarmony 桌面环境中的运行效果。1.4 推荐阅读顺序如果你是第一次做 Qt 适配鸿蒙可以按下面顺序读先看项目基本信息确认目录和包名。再看 Qt SDK 规则避免QT_PREFIX写错。然后看入口函数理解为什么保留main和qtmain。最后看构建、安装和窗口验证命令。二、项目基本信息2.1 信息总览项目内容应用展示名明算项目目录名QtCalculatorLiteBundle Namecom.nutpi.mingsuan项目类型简易计算器核心功能加减乘除四则运算核心实现QML 状态机 响应式 QQuickView界面风格深色计算面板这个表格建议直接写进 README 或项目清单中。当项目数量逐渐增加时目录名、中文名和 Bundle Name 的对应关系非常重要。2.2 目录结构qt_for_harmony/ ├── qtforharmony/ ├── QtCalculatorLite/ │ ├── AppScope/ │ ├── entry/ │ │ ├── build-profile.json5 │ │ └── src/main/ │ │ ├── cpp/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.cpp │ │ │ ├── main.qml │ │ │ └── qml.qrc │ │ └── ets/ │ └── README.md └── qt-docs/目录看起来不复杂但每一层都有明确职责。我建议不要把 Qt SDK 复制进每个项目否则后续更新 SDK 会非常痛苦。2.3 模块职责表模块职责检查重点AppScope声明应用包名、图标、展示名Bundle Name 是否唯一entry/build-profile.json5声明 native 构建入口和 Qt SDK 参数QT_PREFIX 是否为相对路径entry/src/main/cppQt C 与 QML 代码main/qtmain 是否都存在entry/src/main/etsStage Ability 与 XComponent 容器XComponent 是否占满窗口README.md项目说明和运行命令SDK 仓库说明是否写明三、环境准备3.1 必要工具建议准备下面这些工具DevEco Studio 或 OpenHarmony 命令行构建环境hvigorw构建工具hdc设备调试工具Qt for OpenHarmony SDK一个 arm64-v8a 设备或模拟器可以参考文末保留的 OpenHarmony 文档入口。OpenHarmony 文档中心https://docs.openharmony.cn/3.2 Qt SDK 相对路径规则本系列项目统一使用相对路径引用 Qt SDK。也就是说项目目录和qtforharmonySDK 目录保持同级。{ externalNativeOptions: { path: ./src/main/cpp/CMakeLists.txt, arguments: -DQT_PREFIX../qtforharmony, abiFilters: [arm64-v8a] } }关键规则项目需要arguments: -DQT_PREFIX../qtforharmonySDK 文件请到文末保留的 SDK 仓库自取并放到项目同级目录qtforharmony中。3.3 为什么不用绝对路径使用绝对路径时项目只能在你自己的机器上构建。换一台电脑、换一个用户目录、换一个 CI 环境路径就会失效。相对路径的好处是清晰、稳定、可迁移。可以按下面步骤检查确认项目位于qt_for_harmony目录下。确认 SDK 位于qt_for_harmony/qtforharmony。确认entry/build-profile.json5里写的是../qtforharmony。四、工程配置拆解4.1 CMakeLists.txt 的关键点cmake_minimum_required(VERSION 3.5.0) project(qtcalculatorlite) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) get_filename_component(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../.. ABSOLUTE) if (NOT IS_ABSOLUTE ${QT_PREFIX}) get_filename_component(QT_PREFIX ${PROJECT_ROOT}/${QT_PREFIX} ABSOLUTE) endif() list(PREPEND CMAKE_PREFIX_PATH ${QT_PREFIX}) find_package(Qt5 REQUIRED COMPONENTS Core Gui Qml Quick QuickControls2) add_library(entry SHARED main.cpp qml.qrc) target_link_libraries(entry PRIVATE Qt5::Core Qt5::Gui Qt5::Qml Qt5::Quick)这段 CMake 重点做了三件事。第一把相对的QT_PREFIX转成绝对路径。第二把 Qt SDK 加入CMAKE_PREFIX_PATH。第三把 C 入口和qml.qrc打进libentry.so。4.2 构建参数检查表配置项推荐值说明path./src/main/cpp/CMakeLists.txtnative 构建入口arguments-DQT_PREFIX../qtforharmonyQt SDK 相对路径abiFiltersarm64-v8a当前项目验证 ABIcopyCodeResourcefalse避免资源重复处理4.3 qml.qrc 的作用RCCqresourceprefix/filemain.qml/file/qresource/RCCQML 文件被打入 Qt 资源系统后C 侧可以通过qrc:/main.qml加载。这能减少路径依赖也能避免运行时找不到 QML 文件。五、入口函数设计5.1 为什么保留 main 和 qtmain在当前适配方案里libentry.so需要兼容不同 QPA 启动行为。如果只导出qtmain某些版本可能会报Symbol not found: main。如果只保留main又可能不符合已有 QPA 调用链。所以当前项目统一保留两个入口。externCvoidqtmain(){staticResponsiveQuickView*viewnullptr;if(view!nullptr){return;}configureSurfaceFormat();viewnewResponsiveQuickView();loadQml(view);}intmain(intargc,char*argv[]){configureSurfaceFormat();QGuiApplicationapp(argc,argv);ResponsiveQuickView view;if(!loadQml(view)){return-1;}returnapp.exec();}5.2 启动流程启动链路可以理解为HarmonyOS Stage Ability 创建 XComponent 容器。QPA 插件加载libentry.so。main或qtmain初始化 Qt 应用环境。C 侧加载qrc:/main.qml。QML 渲染到 XComponent 对应的原生节点上。5.3 XComponent 容器示意import{NodeController,FrameNode}fromkit.ArkUI;classQtNodeControllerextendsNodeController{makeNode(uiContext:UIContext):FrameNode|null{returnthis.node;}}EntryComponentstruct Index{build(){XComponent({id:qt_xcomponent,type:XComponentType.NODE}).width(100%).height(100%)}}这段 ArkTS 只是示意。真正项目里还需要配合 Qt QPA 插件完成 native node 绑定。六、QML 界面实现6.1 根节点尺寸策略Rectangle { id: root width: 880 height: 1100 color: #F4F6FB property real pageMargin: Math.max(24, Math.min(56, width * 0.045)) property real bodySize: Math.max(18, Math.min(24, width * 0.025)) Column { anchors.fill: parent anchors.margins: root.pageMargin spacing: 16 } }这里的关键是不要把布局写死成一个固定手机尺寸。宽度、间距和字号都可以用根节点尺寸推导。这样最大化、还原和不同分辨率设备上都更稳。6.2 当前项目的核心 QMLGrid { columns: 4 spacing: 10 Repeater { model: [7, 8, 9, ÷, 4, 5, 6, ×] Rectangle { width: 72 height: 72 radius: 8 Text { anchors.centerIn: parent; text: modelData } MouseArea { anchors.fill: parent; onClicked: pressKey(modelData) } } } }这段代码体现了明算的核心功能加减乘除四则运算。真实项目里可以继续拆成多个 QML 组件但演示项目保持单文件更利于阅读。6.3 UI 层级表层级作用设计建议根 Rectangle承载背景和全局尺寸颜色和尺寸统一从这里派生页面 Column/Row控制整体排版避免控件互相覆盖功能卡片展示核心信息半径不超过 8px保持工具感按钮区域触发业务动作用明确文案和稳定尺寸列表或指标区承载动态数据设置 clip避免越界七、核心逻辑拆解7.1 数据模型function pressKey(key) { if (key 0 key 9) { appendDigit(key) return } if (key || key - || key × || key ÷) { chooseOperator(key) } }这个模型只做最小必要的数据组织。演示项目不建议一上来引入数据库、网络层或复杂状态管理。先把交互链路跑通再逐步增强。7.2 业务动作if (operator ÷ rightValue 0) { displayText 不能除以 0 hasError true return }业务动作保持短小有一个好处问题发生时更容易定位。比如按钮点击无响应时可以直接确认是 MouseArea、函数调用还是模型更新的问题。7.3 交互验证步骤建议每次改完 QML 后都做下面这组验证启动应用确认首屏不白屏。点击主要按钮确认状态变化。最大化窗口确认没有黑边。还原窗口确认内容立刻刷新。查看日志确认没有 QML 加载错误。八、窗口缩放适配8.1 曾经遇到的问题在 Qt 适配鸿蒙时窗口最大化或还原后XComponent 尺寸可能已经变化但 Qt 场景没有立即重算。表现出来就是右侧出现黑边或者必须点击一次界面才刷新。注意不要用 XComponent 的尺寸反向调用QWindow::resize()做闭环同步这很容易造成窗口不断缩小极端情况下会缩成一个点。8.2 推荐的刷新思路classResponsiveQuickView:publicQQuickView{public:explicitResponsiveQuickView(QWindow*parentnullptr):QQuickView(parent){setResizeMode(QQuickView::SizeRootObjectToView);connect(this,QWindow::widthChanged,this,[this](int){refreshRootLayout();});connect(this,QWindow::heightChanged,this,[this](int){refreshRootLayout();});}private:voidrefreshRootLayout(){if(rootObject()!nullptr){rootObject()-setSize(QSizeF(size()));rootObject()-polish();rootObject()-update();}requestUpdate();}};这个思路的核心是只刷新 QML 根对象和 scene graph。它不会拿原生节点尺寸反向 resize Qt 窗口因此不会形成尺寸反馈环。8.3 验证命令hdc shell aa start-aEntryAbility-bcom.nutpi.mingsuan-mentrysleep2hdc shell snapshot_display-f/data/local/tmp/mingsuan_screen.jpeg hdcfilerecv /data/local/tmp/mingsuan_screen.jpeg /tmp/mingsuan_screen.jpeg hdc shell uitest dumpLayout-p/data/local/tmp/layout_mingsuan.json-d0如果截图正常、布局树里的 XComponent bounds 与窗口内部区域一致基本可以确认窗口刷新链路是通的。九、构建、安装与运行9.1 构建 HAPcd/new/ugc/qt_for_harmony/QtCalculatorLite /Users/luqingjiedemac/ohos/command-line-tools/bin/hvigorw assembleHap--stacktrace构建成功后会看到BUILD SUCCESSFUL。HAP 默认输出路径如下。entry/build/default/outputs/default/entry-default-unsigned.hap9.2 安装并启动hdcinstall-rentry/build/default/outputs/default/entry-default-unsigned.hap hdc shell aa start-aEntryAbility-bcom.nutpi.mingsuan-mentry hdc shell pidof com.nutpi.mingsuan如果pidof能返回进程号就说明应用已经启动。接着再看截图确认 QML 是否渲染正常。9.3 日志观察hdc shell hilog-rhdc shell aa start-aEntryAbility-bcom.example.demo-mentrysleep2hdc shell hilog-x|tail-n120常见非阻塞日志包括 NAPI 验证提示、签名配置提示、图形栈内部符号提示。真正需要优先处理的是 QML 加载失败、入口符号缺失、动态库找不到。十、常见问题与排查10.1 问题表问题可能原因排查方式白屏QML 未加载或入口函数不匹配检查 hilog 和 qrc 路径找不到 main只导出了 qtmain同时保留 main 和 qtmain构建失败QT_PREFIX 不正确检查 …/qtforharmony 是否存在窗口黑边根对象未随窗口刷新检查 QQuickView resize 策略按钮无响应MouseArea 层级或 enabled 状态错误用最小按钮复现文字溢出字号和容器不匹配使用 elide 或 wrapMode10.2 推荐排查顺序遇到问题时不要同时改很多地方。建议按下面顺序处理先确认 HAP 能构建成功。再确认应用能被aa start拉起。然后检查 hilog 是否有入口符号问题。最后看 QML 布局、交互和窗口缩放。经验构建问题、启动问题、渲染问题要分开排查。混在一起改最后很难判断是哪一步修好的。十一、质量自检11.1 运行验证矩阵验证项预期结果当前项目建议普通启动显示首屏看到 明算 主界面主要交互功能状态变化加减乘除四则运算最大化界面铺满窗口无黑边无延迟刷新还原尺寸恢复正常不缩成点不等待点击刷新日志无入口错误不出现 Symbol not found: main11.2 发布前检查清单发布项目或文章前我建议至少检查这些内容README 是否写明 SDK 仓库和QT_PREFIX规则Bundle Name 是否和其他项目冲突应用展示名是否已经产品化HAP 是否能重新构建截图是否来自实际运行效果最大化和还原是否已经验证十二、可以继续扩展什么12.1 功能增强方向围绕明算后续可以做这些增强把“数字输入”做成更完整的产品级体验把“加减乘除”做成更完整的产品级体验把“小数点处理”做成更完整的产品级体验把“正负号切换”做成更完整的产品级体验把“除零提示”做成更完整的产品级体验增加本地持久化能力增加主题切换增加更多输入校验和异常提示12.2 工程增强方向工程层面可以按下面路线演进把通用的 ResponsiveQuickView 抽成公共模板。把 README 的 SDK 规则变成统一脚本检查。把截图验证命令纳入日常验收流程。把项目列表和 Bundle Name 放进表格统一维护。十三、完整命令速查13.1 从构建到启动cd/new/ugc/qt_for_harmony/QtCalculatorLite /Users/luqingjiedemac/ohos/command-line-tools/bin/hvigorw assembleHap--stacktracehdcinstall-rentry/build/default/outputs/default/entry-default-unsigned.hap hdc shell aa start-aEntryAbility-bcom.nutpi.mingsuan-mentry13.2 截图和布局树hdc shell snapshot_display-f/data/local/tmp/mingsuan_screen.jpeg hdcfilerecv /data/local/tmp/mingsuan_screen.jpeg /tmp/mingsuan_screen.jpeg hdc shell uitest dumpLayout-p/data/local/tmp/layout_mingsuan.json-d0hdcfilerecv /data/local/tmp/layout_mingsuan.json /tmp/layout_mingsuan.json13.3 清理和重建rm-rfentry/build entry/.cxx .hvigor /Users/luqingjiedemac/ohos/command-line-tools/bin/hvigorw assembleHap--stacktrace十四、保留资源入口14.1 OpenHarmony 文档OpenHarmony 文档中心docs.openharmony.cn这个入口用于继续查询 Ability、XComponent、设备调试和系统能力相关资料。14.2 Qt for Harmony SDKQt for Harmony SDK 仓库https://AtomGit.com/nutpi/qtforharmony_sdk这个入口用于获取本文项目依赖的 Qt 适配鸿蒙 SDK 文件。14.3 为什么只保留这两个正文资源技术文章不一定需要堆很多链接。这五篇文章保留社区入口、OpenHarmony 文档和 SDK 仓库三个关键链接读者路径更短也更适合复制到 CSDN 发布。总结这篇文章从工程、配置、入口、QML、构建、安装和验证几个角度拆解了明算。它不是一个复杂应用但已经覆盖 Qt 适配鸿蒙项目最关键的闭环能构建、能启动、能显示、能随窗口尺寸刷新。下一篇可以继续扩展新的业务类型把同一套 Qt for OpenHarmony 工程规则复制到更多产品化小应用里。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力
http://www.zskr.cn/news/1361965.html

相关文章:

  • Rust Trait系统设计模式:实现灵活的多态和代码复用
  • 鸿蒙PC:鸿蒙electron跨端框架PC链接雷达实战:把本地收藏夹升级成可巡检的链接管理面板
  • 【带RL负载的全波桥式整流器】功能齐全的单相非控整流器(Simulink)
  • 大模型从0训练LLaMA全流程实战——基于昇腾910B集群
  • 终极指南:如何一键检测微信单向好友,告别隐形删除困扰 [特殊字符]
  • LeetCode 1314:矩阵区域和 | 二维前缀和
  • LeetCode 930:和相同的二元子数组 | 前缀和与哈希表
  • LeetCode 1424:对角线遍历 II | 前缀和分组
  • 2026年Q2四川应急物资厂家评测:应急消防设备厂家/应急物资厂家电话/抗洪抢险应急设备/消防工具厂家/消防智能设备/选择指南 - 优质品牌商家
  • 2026成都靠谱金属建材回收公司推荐:工厂废料回收/工地废料回收/库房物资回收/废旧机器回收/废铁回收/废铜回收/选择指南 - 优质品牌商家
  • 2026年Q2西南地区测绘仪租赁服务机构排行盘点:华测rtk/华测无人船/地形测量/大疆无人机/徕卡全站仪/手持扫描仪/选择指南 - 优质品牌商家
  • 面向创意生成 Agent 的 Harness 随机种子管理
  • 2026年当下河北工程网格布实力厂商剖析与精准选型指南 - 2026年企业推荐榜
  • 2026气体扩散层权威供应商精选推荐:气体扩散过滤板、气体扩散金属板、气体扩散钛板、气体扩散钛滤板、电解槽滤板选择指南 - 优质品牌商家
  • 零售智能体上线周期缩短至11天,如何复用这3套经GDPR+等保三级认证的Agent模板?
  • AI Agent Harness Engineering 在房地产中的应用:智能推荐与价值评估
  • 国曙GOSHINE正式亮相:一家人力资源服务机构的“长期主义”转向!
  • 学 Simulink—— 双定子永磁同步电机(DS‑PMSM)的协同控制与转矩提升仿真(带 MATLAB 脚本(直接运行))
  • 首个「音频-视觉智能」综述:大模型时代的AVI,究竟走到哪一步了?
  • 2026年5月新发布:Shiwosi史沃斯以工业级硬实力重塑车间清洁标准 - 2026年企业推荐榜
  • 黄仁勋放话:AI基建要烧掉4万亿美元 谁买单?
  • React 性能优化:从 3 秒卡顿到 60 帧流畅,我做了这 5 件事
  • 【能源AI Agent价值验证白皮书】:实测降低风电场故障预测误报率63%,缩短停机决策时间至8.2分钟
  • 2026年Q2国内矿箱厂家实力排行及联系方式参考:集装箱卫生间/集装箱售卖亭/集装箱售楼部/集装箱房屋厂家联系电话/选择指南 - 优质品牌商家
  • 加速科研、提出新假设:谷歌重磅推出Co-Scientist模型
  • 毕业论文神器!2026年必备AI论文软件榜单,免费版也能写合规初稿
  • 股权纠纷律师哪个好?陈杰律师:最高院再审胜诉经验 - 外贸老黄
  • 微服务安全防护实战:OAuth2与JWT鉴权
  • JWT令牌安全实践详解
  • Go语言错误处理:最佳实践