HarmonyOS鸿蒙PC的QT应用开发:QT项目运行原理与 EmbeddedUIExtensionAbility介绍

好消息,2026年3.31日,QT官方正式发布鸿蒙版QT。本次开源发布正式推出面向鸿蒙系统平板和PC设备的Qt 5.12.12 LTS 适配版本,在完整保留 Qt 5.12.12 核心能力(含界面渲染、信号槽机制、跨平台 I/O、网络通信及数据库模块)的基础上,深度适配鸿蒙系统架构。本版本可降低开发者跨平台移植成本,加速 Qt 与鸿蒙生态融合,助力多场景鸿蒙应用高效开发。

QT官方鸿蒙版开源地址https://wiki.qt.io/Qt5.12.12_Open_Source_Release_for_HarmonyOS_zh

QT官方文档地址https://wiki.qt.io/Qt_for_OpenHarmony/zh

前言

在 HarmonyOS 上运行 Qt 应用,跟传统的PC上的QT应用不同。

传统的PC上的QT应用是使用QtCreator开发完成后,直接编译为可执行文件exe.。 而鸿蒙版QT的开发流程,则是使用鸿蒙版QT的SDK和qmake工具链,最终的编译产物为.so. 之后呢还需要鸿蒙的QT工程项目模版,把so加载进去,将应用编译打包为hap或app包。

在HarmonyOS 上运行 Qt 应用,通常需要三层协作:系统 Ability 与窗口ArkUI 中的原生节点(XComponent) ,以及 Qt 平台的 QPA 插件(本模板中为 libqohos.so 。当产品希望在「不整页跳转」的前提下,把 Qt 界面嵌进另一个界面的指定区域时,系统提供了 EmbeddedUIExtensionAbility(嵌入式 UI 扩展能力) :由宿主页面的 EmbeddedComponent 发起一次嵌入会话,扩展侧在独立能力中加载页面并完成绘制与交互。

本文以鸿蒙项目模版,仓库内 ohostemplateforqtapplication_20260331 为例,介绍下QT项目结构运行原理与 EmbeddedUIExtensionAbility。

ohostemplateforqtapplication是用于构建最终 OpenHarmony Qt 应用程序的 DevEco 项目模板。这将用于在 HarmonyOS 设备上运行 Qt 应用程序。 开发者也可以从以下链接获取最新项目工程模版: http://codereview.qtcompany.cn:29416/template/

应用级 app.json5、工程级 build-profile.json5、模块级 module.json5ArkTS 与原生库调用关系 ,说明模板工程的运行原理,并单独梳理 EmbeddedUIExtensionAbility 在本项目中的职责与数据流。文中代码与配置均来自当前仓库快照;系统 API 行为以你所使用的 HarmonyOS SDK 版本及官方文档为准。


1. 核心概念

1.1 Qt 在鸿蒙模板中的位置

  • 入口形态 :模板将 主界面 实现为 UIAbility 子类 QAbility,生命周期各阶段委托给 libqohos.so 暴露的 NAPI(代码中以 import qpa from 'libqohos.so' 引用),由 Qt for OpenHarmony / HarmonyOS 的 QPA 与系统窗口、输入等对接。
  • 绘制落点 :ArkUI 页面通过 XComponenttype: XComponentType.NODElibraryname: 'qohos' 创建原生节点;QPA 在该节点上挂载 Qt 的渲染与事件循环逻辑。主窗口与嵌入扩展会话各对应一套页面与节点,但共用同一套 qohos 原生模块名。
  • 业务库 :实际运行的 Qt 可执行形态为共享库(如 libcalculator.so),名称在 QtAppConstants.etsAPP_LIBRARY_NAME 中配置,并需与 entry/libs/<ABI>/ 下放置的 .so 一致。

1.2 EmbeddedUIExtensionAbility 在本项目中的角色

  • 系统定义EmbeddedUIExtensionAbility 是嵌入式 UI 类扩展能力,与 UIExtension 会话(UIExtensionContentSession 绑定;每次嵌入对应一次会话创建与销毁。
  • 模板封装QBaseEmbeddedUiExtensionAbility 继承系统基类,在 onCreateonSessionCreateonSessionDestroyonDestroy 中统一转发到 qpa.handleQEmbeddedUiExtensionAbility*;并在首次创建时用 uiExtensionMode: true 初始化 Qt 应用上下文,使 QPA 按「扩展嵌入」路径而非普通全屏 Ability 路径工作。
  • 双扩展名module.json5 声明了两个嵌入式扩展:QEmbeddedUiExtensionAbilityextensionProcessMode: "instance")与 QBundledEmbeddedUiExtensionAbilityextensionProcessMode: "bundle"),便于在同一模板内对比或选用不同进程/打包语义(具体调度以系统实现为准)。

1.3 宿主侧 EmbeddedComponent

  • 使用位置 :模板在 feature 模块 qEmbeddedUiExtensionHost 中提供演示 Ability EmbedQtAbility,其页面通过 EmbeddedComponent(want, EmbeddedType.EMBEDDED_UI_EXTENSION) 指定要拉起的扩展能力名称与参数。
  • Want 约定EmbedQtAbilitybundleName 设为当前应用包名,abilityName 设为 QEmbeddedUiExtensionAbility,并把启动参数中以 io.qt. 为前缀的项传入扩展,供 Qt 侧读取。

2. 工程与模块结构

2.1 应用标识(AppScope/app.json5)

应用级配置定义包名与版本信息,嵌入场景下 Want.bundleName 必须与之一致 (模板在代码中用 getBundleInfoForSelfSync 取当前包名,避免硬编码错误)。

json 复制代码
//:ohostemplateforqtapplication_20260331/AppScope/app.json5
{
  "app": {
    "bundleName": "com.ohos.ohosqttemplate",
    "configuration": "$profile:configuration",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "icon": "$media:app_icon",
    "label": "$string:app_name"
  }
}

2.2 多模块工程(build-profile.json5)

工程级 build-profile.json5 声明两个模块:entry (主模块,含 Qt 与嵌入式扩展)与 qEmbeddedUiExtensionHost (feature,演示嵌入宿主)。构建产物为同一应用包内的多个 HAP/HSP(以实际打包方式为准),因此 feature 中的 EmbeddedComponent 可以指向 entry 中声明的 embeddedUI 能力。

与 SDK 相关的字段示例(签名等本地路径略):

  • compatibleSdkVersiontargetSdkVersion:决定可用的 Ability / Extension API 集。
  • modules 数组:每项 name + srcPath 对应磁盘上的子工程目录。

2.3 entry 模块配置要点(entry/src/main/module.json5)

下列字段直接影响运行时行为,建议对照阅读。

配置项 本模板取值 含义说明
type entry 应用主模块。
srcEntry ./ets/qabilitystage/QAbilityStage.ets 指定 AbilityStage 实现,用于多实例、多进程键值与 Qt 全局初始化钩子。
mainElement QAbility 默认启动的 UIAbility 名称。
deviceTypes tablet2in1 声明支持的设备类型;注释中说明 phone 与最小化还原存在已知问题(QTFOROH-1076)。
abilitiesQAbility launchType: "specified"isolationProcess: true 多实例与独立进程相关配置,与 QAbilityStage.onAcceptWant / onNewProcessRequest 配合。
extensionAbilities 两条 type: "embeddedUI" 声明嵌入式 UI 扩展;extensionProcessMode 分别为 instancebundle

嵌入式扩展与主 Ability 的声明片段如下:

json 复制代码
//:ohostemplateforqtapplication_20260331/entry/src/main/module.json5
    "extensionAbilities": [
      {
        "name": "QEmbeddedUiExtensionAbility",
        "srcEntry": "./ets/qability/QEmbeddedUiExtensionAbility.ets",
        "icon": "$media:layered_image",
        "type": "embeddedUI",
        "description": "",
        "exported": true,
        "extensionProcessMode": "instance"
      },
      {
        "name": "QBundledEmbeddedUiExtensionAbility",
        "srcEntry": "./ets/qability/QBundledEmbeddedUiExtensionAbility.ets",
        "icon": "$media:layered_image",
        "type": "embeddedUI",
        "description": "",
        "exported": true,
        "extensionProcessMode": "bundle"
      }
    ],
    "abilities": [
      {
        "name": "QAbility",
        "srcEntry": "./ets/qability/QAbility.ets",
        "launchType": "specified",
        // ...
        "exported": true,
        "isolationProcess": true,

要点:type 必须为 embeddedUI ,否则系统不会按嵌入式 UI 扩展路由;exported: true 允许同应用内通过 Want 访问该能力名称。

2.4 feature 宿主模块(qEmbeddedUiExtensionHost/src/main/module.json5)

该模块 仅声明普通 UIAbility ,不声明 extensionAbilities;嵌入的扩展能力仍落在 entry 中,由运行时根据包内合并后的清单解析。

json 复制代码
//:ohostemplateforqtapplication_20260331/qEmbeddedUiExtensionHost/src/main/module.json5
{
  "module": {
    "name": "qEmbeddedUiExtensionHost",
    "type": "feature",
    "description": "$string:module_desc",
    "mainElement": "EmbedQtAbility",
    "deviceTypes": [
      "2in1",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EmbedQtAbility",
        "srcEntry": "./ets/embedqtability/EmbedQtAbility.ets",
        // ...
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ],
  }
}

mainElement: "EmbedQtAbility" 表示从桌面图标等方式启动该 feature 时,默认进入嵌入演示 Ability。


3. 代码链路:从进程启动到 Qt 绘制

3.1 AbilityStage 与 Qt 单次初始化(QAbilityStage.ets)

QAbilityStage 在普通模式与扩展模式下都会调用 qpa.setupQtApplication,区别是 uiExtensionModeabilityClassName 。扩展能力首次 onCreate 时走 initQtAppContextInUiExtensionMode,确保 QPA 以嵌入扩展语义初始化。

ts 复制代码
//:ohostemplateforqtapplication_20260331/entry/src/main/ets/qabilitystage/QAbilityStage.ets
  private static initQtAppContextImpl(appContext: common.ApplicationContext, abilityClassName: string, uiExtensionMode: boolean): void {
    if (!QAbilityStage.setupQtApplicationCalled) {
      hilog.info(LOG_DOMAIN, LOG_TAG, 'QAbilityStage::initQtAppContextImpl: init with uiExtensionMode=' + uiExtensionMode);
      QAbilityStage.setupQtApplicationCalled = true;
      qpa.setupQtApplication({
        appContext: appContext,
        modules: QtUtils.getModulesMapForQt(),
        appName: APP_LIBRARY_NAME,
        appArgs: QAbilityStage.appArgs,
        abilityClassName: abilityClassName,
        uiExtensionMode: uiExtensionMode,
        _unusedQChildProcess: new QChildProcess(),
      });
    } else {
      hilog.info(LOG_DOMAIN, LOG_TAG, 'QAbilityStage::initQtAppContextImpl: already initialized');
    }
  }

  public static initQtAppContextIfNeeded(appContext: common.ApplicationContext): void {
    QAbilityStage.initQtAppContextImpl(appContext, QAbility.name, false);
  }

  public static initQtAppContextInUiExtensionMode(appContext: common.ApplicationContext, abilityClassName: string): void {
    QAbilityStage.initQtAppContextImpl(appContext, abilityClassName, true);
  }

APP_LIBRARY_NAME 来自 QtAppConstants.ets(当前为 libcalculator.so),需与部署到设备上的 Qt 应用库文件名一致。

ts 复制代码
//:ohostemplateforqtapplication_20260331/entry/src/main/ets/common/QtAppConstants.ets
export const APP_LIBRARY_NAME = 'libcalculator.so';
export const LOG_DOMAIN = 0x0000;
export const LOG_TAG = 'ohosQtTemplate';

3.2 主 UIAbility:QAbility.ets

主入口将系统回调逐一交给 QPA,形成与原生鸿蒙应用一致的「创建 → 窗口阶段 → 前后台 → 销毁」节奏。

ts 复制代码
//:ohostemplateforqtapplication_20260331/entry/src/main/ets/qability/QAbility.ets
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
    hilog.info(LOG_DOMAIN, LOG_TAG, 'QAbility::onCreate(): want.parameters: ' + JSON.stringify(want.parameters));
    QAbilityStage.initQtAppContextIfNeeded(this.context.getApplicationContext());
    qpa.handleAbilityOnCreate(this, want, launchParam);
  }

  onDestroy(): void | Promise<void> {
    hilog.info(LOG_DOMAIN, LOG_TAG, 'QAbility::onDestroy()');
    return qpa.handleAbilityOnDestroy(this);
  }
  // ...
  onWindowStageCreate(windowStage: Window.WindowStage) {
    hilog.info(LOG_DOMAIN, LOG_TAG, 'QAbility::onWindowStageCreate(): this.launchWant.parameters: ' + JSON.stringify(this.launchWant.parameters));
    qpa.handleAbilityOnWindowStageCreate(this, windowStage);
  }

3.3 嵌入式扩展基类:QBaseEmbeddedUiExtensionAbility.ets

扩展侧在 onCreate 中调用 initQtAppContextInUiExtensionMode,随后各会话阶段同样进入 QPA。子类 QEmbeddedUiExtensionAbility / QBundledEmbeddedUiExtensionAbility 仅区分日志用的类名,行为一致。

ts 复制代码
//:ohostemplateforqtapplication_20260331/entry/src/main/ets/qability/QBaseEmbeddedUiExtensionAbility.ets
  onCreate(launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(LOG_DOMAIN, LOG_TAG, '%{public}s::onCreate()', this.getClassName());
    QAbilityStage.initQtAppContextInUiExtensionMode(this.context.getApplicationContext(), this.getClassName());
    qpa.handleQEmbeddedUiExtensionAbilityOnCreate(this, launchParam);
  }

  onDestroy(): void | Promise<void> {
    hilog.info(LOG_DOMAIN, LOG_TAG, '%{public}s::onDestroy()', this.getClassName());
    return qpa.handleQEmbeddedUiExtensionAbilityOnDestroy(this);
  }

  onSessionCreate(want: Want, session: UIExtensionContentSession): void {
    hilog.info(LOG_DOMAIN, LOG_TAG, '%{public}s::onSessionCreate()', this.getClassName());
    qpa.handleQEmbeddedUiExtensionAbilityOnSessionCreate(this, want, session);
  }

  onSessionDestroy(session: UIExtensionContentSession): void {
    hilog.info(LOG_DOMAIN, LOG_TAG, '%{public}s::onSessionDestroy()', this.getClassName());
    qpa.handleQEmbeddedUiExtensionAbilityOnSessionDestroy(this, session);
  }

3.4 XComponent 与 qohos:主窗口与扩展会话页面

主窗口节点页面(示例为 MainWindowNativeNode.ets)与扩展内页面 UiExtensionNativeNode.ets 结构相同:在 Stack 中放置 XComponent,指定 libraryname: 'qohos',由 QPA 注册的 native 模块承接 Qt 场景图。

ts 复制代码
//:ohostemplateforqtapplication_20260331/entry/src/main/ets/pages/MainWindowNativeNode.ets
  build() {
    Stack() {
      if (this.createInfo !== undefined) {
        XComponent({
          type: XComponentType.NODE,
          id: this.createInfo.xComponentId,
          libraryname: 'qohos'
        })
  	    .onAttach(this.createInfo.onAttach)
  	    .onAppear(this.createInfo.onAppear)
  	    .onDisAppear(this.createInfo.onDisAppear)
  	    .width('100%')
  	    .height('100%')
      }
    }
ts 复制代码
//:ohostemplateforqtapplication_20260331/entry/src/main/ets/pages/UiExtensionNativeNode.ets
      if (this.createInfo !== undefined) {
        XComponent({
          type: XComponentType.NODE,
          id: this.createInfo.xComponentId,
          libraryname: 'qohos'
        })
          .onAppear(this.createInfo.onAppear)
          .onDisAppear(this.createInfo.onDisAppear)
          .onAttach(() => {
            if (this.createInfo !== undefined) {
              this.createInfo.onAttach?.(this.getUIContext());
            } else {
              hilog.error(LOG_DOMAIN, LOG_TAG, 'Cannot call onAttach, createInfo is undefined');
            }
          })
          .width('100%')
          .height('100%')
      }

3.5 嵌入演示:EmbedQtAbility → Index → EmbeddedComponent

EmbedQtAbilityonWindowStageCreate 中过滤 io.qt.* 参数,构造指向 QEmbeddedUiExtensionAbilityWant,写入 LocalStorage 后加载 pages/Index

ts 复制代码
//:ohostemplateforqtapplication_20260331/qEmbeddedUiExtensionHost/src/main/ets/embedqtability/EmbedQtAbility.ets
  onWindowStageCreate(windowStage: window.WindowStage): void {
    const qtParameterPrefix: string = 'io.qt.';

    let qtParameters: Record<string, Object> = {};
    if (this.launchWant.parameters) {
      Object.keys(this.launchWant.parameters)
        .filter(key => key.startsWith(qtParameterPrefix))
        .forEach(qtKey => qtParameters[qtKey] = this.launchWant.parameters![qtKey]);
    }

    let localStorageProperties: Record<string, Want> = {};
    localStorageProperties[EmbedQtAbility.EMBEDDED_QT_START_WANT_PROP_NAME] = {
      bundleName: bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT).name,
      abilityName: 'QEmbeddedUiExtensionAbility',
      parameters: qtParameters,
    };
    windowStage.loadContent('pages/Index', new LocalStorage(localStorageProperties))
  }

Index.ets 取出上述 Want,交给 EmbeddedComponentImpl

ts 复制代码
//ohostemplateforqtapplication_20260331/qEmbeddedUiExtensionHost/src/main/ets/pages/Index.ets
@Entry
@Component
struct Index {
  private want: Want = LocalStorage.getShared().get<Want>(EmbedQtAbility.EMBEDDED_QT_START_WANT_PROP_NAME) as Want;

  build() {
    Row() {
      Column() {
        EmbeddedComponentImpl({want: this.want})
          .width('100%')
          .height('100%')
      }
      .width('100%')
    }
    .height('100%')
  }
}

EmbeddedComponentImpl.etsEmbeddedComponentwant 不可省略 ,否则无法拉起嵌入式扩展;onTerminated / onError 用于观测嵌入失败或扩展退出。

ts 复制代码
//ohostemplateforqtapplication_20260331/qEmbeddedUiExtensionHost/src/main/ets/components/EmbeddedComponentImpl.ets
  build() {
    Row() {
      Column() {
        Text("Hello from EmbeddedComponentImpl")

        // This is the embedded component used to embed Qt application. Don't remove it.
        EmbeddedComponent(this.want, EmbeddedType.EMBEDDED_UI_EXTENSION)
          .width('100%')
          .height('90%')
          .onTerminated((info: TerminationInfo) => {
            console.warn(`Terminarion: code = ${info.code}, want = ${JSON.stringify(info.want)}`);
          })
          .onError((error: BusinessError) => {
            console.error(`Error: code = ${error.code}, message = '${JSON.stringify(error.message)}'`);
          })
      }
      .width('100%')
    }
    .height('100%')
  }

3.6 原生侧 entry 库(entry/src/main/cpp)

模板附带最小 libentry.sohello.cpp + NAPI),与 libqohos.so、Qt 应用及 Qt 依赖库 分工不同:前者多为示例或胶水代码,Qt 运行主体由 QPA 与 Qt 共享库承担。CMake 仅声明 entrylibace_napi.z.so 链接,实际 Qt 库通过 entry/libs/<ABI>/ 部署。

bash 复制代码
#ohostemplateforqtapplication_20260331/entry/src/main/cpp/CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
project(ohosQtTemplate)

set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})

include_directories(${NATIVERENDER_ROOT_PATH}
                    ${NATIVERENDER_ROOT_PATH}/include)

add_library(entry SHARED hello.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so)

4. 生命周期与数据流小结

4.1 主 Ability 与扩展 Ability 对比

阶段 QAbility(UIAbility) QBaseEmbeddedUiExtensionAbility
应用级 Qt 初始化 initQtAppContextIfNeededuiExtensionMode: false initQtAppContextInUiExtensionModeuiExtensionMode: true
窗口 onWindowStageCreate 等,由 QPA 绑定主 WindowStage 无独立「全屏窗口阶段」语义;由 onSessionCreate 进入会话 UI
会话 不适用 onSessionCreate / onSessionDestroy 对应每次嵌入
原生绘制载体 MainWindowNativeNode 中 XComponent UiExtensionNativeNode 中 XComponent

4.2 整体数据流(示意)

entry
qEmbeddedUiExtensionHost
Want 指向同包扩展
EmbedQtAbility
LocalStorage 中的 Want
EmbeddedComponent
QEmbeddedUiExtensionAbility
libqohos.so / QPA
UiExtensionNativeNode XComponent


5. 集成与调试时注意点

  1. 库文件部署 :将 Qt 应用依赖的qt库的 .solibqohos.so 及依赖的 Qt 模块库复制到 entry/libs/<ABI>/(如 arm64-v8ax86_64),与模拟器或真机 ABI 一致。
  2. 应用库名 :修改 QtAppConstants.etsAPP_LIBRARY_NAME,与目标 .so 文件名一致。
  3. 设备类型 :entry 与 host 模块当前均面向 平板 / 2in1 ;若需手机,需评估 module.json5 注释中的最小化还原问题后再改 deviceTypes
  4. 嵌入目标 :演示页默认拉起 QEmbeddedUiExtensionAbility;若需改用 QBundledEmbeddedUiExtensionAbility,应同步修改 EmbedQtAbility.ets 中的 abilityName 与测试场景。
  5. 日志 :统一 TAG 为 ohosQtTemplate(见 QtAppConstants.ets),便于在 HiLog 中过滤主流程与扩展流程。

6. 与传统 PC 桌面 Qt 应用的差异

  1. 进程与入口不是 main() 独占

    系统先按鸿蒙规则拉起 Ability。全屏场景走 QAbility(UIAbility);需要嵌在别的界面里时走 EmbeddedUIExtensionAbility 子类,由宿主页面的 EmbeddedComponent 触发会话。

  2. Qt 由 QPA 插件接入系统,而不是直接对接 Win32/X11

    ArkTS 通过 import qpa from 'libqohos.so' 把 onCreate / onWindowStageCreate / 前后台 / 销毁 以及扩展侧的 onSessionCreate / onSessionDestroy 等转给 Qt for OHOS 的 QPA(libqohos.so)。也就是说:鸿蒙生命周期 → NAPI → QPA → Qt 事件循环与窗口逻辑。

  3. 绘制表面是 ArkUI 的 XComponent,而不是系统原生 HWND 一层到底

    主窗口和嵌入场景都在 ArkUI 里用 XComponent,type: NODE,libraryname: 'qohos' 留出一块原生区域;QPA 在这块 NODE 上挂接 OpenGL/渲染与输入。模板里对应 MainWindowNativeNode.ets 与 UiExtensionNativeNode.ets。

  4. "可执行文件"形态是共享库 + 配置名

    业务 Qt 程序一般是 entry/libs// 下的 .so(如 QtAppConstants.ets 里的 APP_LIBRARY_NAME),再配合 libqohos.so 和 Qt 依赖库 一起打包进 HAP。没有传统 PC 上那种用户双击的单一 .exe 作为主入口(入口是鸿蒙 Ability)。

  5. 全局初始化与多实例

    QAbilityStage 里 setupQtApplication 只应执行一次,并区分普通模式与 uiExtensionMode: true 的嵌入模式;module.json5 里 launchType / isolationProcess 等与 onAcceptWant / onNewProcessRequest 一起服务于多实例、进程隔离等鸿蒙能力。

本模板工程中,Qt 并不是「从 main() 起独占进程、直接对接 Win32/X11/Wayland/Cocoa」的传统桌面形态,而是落在 HarmonyOS Ability 模型 之内:由 QAbility(UIAbility)或 EmbeddedUIExtensionAbility 子类 作为系统入口,经 libqohos.so 将 Ability / Session 生命周期交给 QPA,再把界面画在 ArkUI XComponentlibraryname: 'qohos' 所暴露的原生节点上。

除下表外,还可记住三点:入口在 Ability 而非仅 main()平台抽象层是 ohos QPA 而非 windows/xcb 等业务常以 .so + APP_LIBRARY_NAME 形式部署于 entry/libs/<ABI>/

维度 传统 PC(Windows / Linux / macOS) 本鸿蒙 Qt 模板(ohostemplateforqtapplication_20260331
程序入口 main() 中创建 QApplication / QGuiApplicationexec() 系统拉起 UIAbility / ExtensionAbility ;ArkTS 在 onCreateonWindowStageCreate 等回调中调用 qpa.handleAbilityOnCreate 等,由 QPA 驱动 Qt
平台插件(QPA) windowsxcb / waylandcocoa 等,直连各 OS 窗口与输入栈 libqohos.so ,衔接 Ability、WindowStage、扩展 SessionXComponent
窗口与 UI 框架 Qt 窗口QWidget / QWindow)为主,占满或管理自有层级 ArkUI 页面 + XComponent 原生区域 ;全屏走 MainWindowNativeNode,嵌入走 UiExtensionNativeNode;宿主侧可用 EmbeddedComponent 拉起 EmbeddedUIExtensionAbility
打包与部署 安装目录或安装包中的 可执行文件.exe / ELF)及依赖 DLL/so HAP 模块 ;Qt 应用多为 entry/libs/<ABI>/ 下的 .so ,与 libqohos.so、Qt 依赖库 一并随包安装;入口能力名在 module.json5 ,应用库名在 QtAppConstants.etsAPP_LIBRARY_NAME
生命周期 进程启动到退出大致对应应用存活期,前后台多与窗口最小化等相关 Ability 前后台、WindowStage 创建销毁、嵌入场景的 onSessionCreate / onSessionDestroy 强绑定,需与 QPA 对齐
设备与系统能力 由桌面环境与用户权限模型决定 module.json5deviceTypes权限声明多模块(entry + feature)真机/模拟器 ABI 约束

桌面 Qt 可概括为「Qt 即应用外壳」;鸿蒙模板则是「系统 Ability + ArkUI 壳 + XComponent 锚点 + ohos QPA 」承载 Qt;嵌入能力再叠一层 同包 embeddedUI 扩展与 EmbeddedComponent 。从 PC 迁来时,需改写入口与打包形态,并在调试中习惯用 HiLogAbility 状态 观察运行阶段,而非仅依赖桌面上的进程列表或控制台。


总结

鸿蒙版 Qt 项目模板 ohostemplateforqtapplication_20260331 通过 QAbility + libqohos.so 实现常规全屏 Qt 应用,通过 QBaseEmbeddedUiExtensionAbility + module.json5embeddedUI 声明 提供可被 EmbeddedComponent 嵌入的能力,并在 feature 模块 中用 EmbedQtAbilityEmbeddedComponent 走完端到端演示链路。

理解本模板的关键在于:清单中的 extensionProcessModetype: embeddedUIArkTS 侧对 QPA 的生命周期转发 ,以及 XComponent NODE 与 libraryname: 'qohos' 作为 Qt 渲染锚点。在此基础上的业务开发,主要集中在 Qt 侧功能、APP_LIBRARY_NAME 与 Want 参数约定,以及权限与 deviceTypes 的调整。


最后,欢迎加入开源鸿蒙开发者社区交流:https://harmonypc.csdn.net/

附录:延伸阅读

以下链接供查阅嵌入式 UI 扩展与 HarmonyOS Ability 相关内容:

  1. HarmonyOS 嵌入式 UI 扩展组件实战 - 博客园

  2. HarmonyOS 应用开发中 EmbeddedUIExtensionAbility:跨进程 UI 嵌入 - SegmentFault

  3. 知乎专栏

  4. https://wiki.qt.io/Qt_for_OpenHarmony/zh?login=from_csdn

  5. https://wiki.qt.io/Qt5.12.12_Open_Source_Release_for_HarmonyOS_zh

官方文档请优先参考:HarmonyOS 开发者官网

相关推荐
张健11564096482 小时前
QT创建线程
开发语言·qt
2301_822703202 小时前
大学生体质健康测试全景测绘台:基于鸿蒙Flutter的多维数据可视化与状态管理响应架构
算法·flutter·信息可视化·架构·开源·harmonyos·鸿蒙
独特的螺狮粉2 小时前
生命科学实验室经费极简记账簿:基于鸿蒙Flutter的极简主义状态响应与流式布局架构
flutter·华为·架构·开源·harmonyos
梁山好汉(Ls_man)2 小时前
鸿蒙_组件导航Navigation的基础用法
华为·harmonyos·鸿蒙·arkui
提子拌饭1332 小时前
红细胞代偿性增殖与睡眠剥夺的对照演算引擎:基于鸿蒙Flutter的微观流体力学粒子渲染架构
flutter·华为·架构·开源·harmonyos·鸿蒙
森G2 小时前
51、Move方式创建线程---------多线程
c++·qt
互联网散修2 小时前
鸿蒙 ArkTS 自定义下拉刷新组件:从手势冲突到完美解决方案
华为·harmonyos
小成Coder2 小时前
UniApp 如何调用鸿蒙预加载
uni-app·harmonyos·鸿蒙
浮芷.2 小时前
Flutter 框架跨平台鸿蒙开发 - 智能家电故障诊断应用
运维·服务器·科技·flutter·华为·harmonyos·鸿蒙