Jump to content

Qt for HarmonyOS/api inconsistencies on harmonyos: Difference between revisions

From Qt Wiki
No edit summary
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''English'''
[[Qt_for_HarmonyOS/api_inconsistencies_on_harmonyos_zh|中文]]
= Qt for HarmonyOS: API Compatibility and Porting Notes =
= Qt for HarmonyOS: API Compatibility and Porting Notes =


Line 46: Line 49:
* Use '''QtOhosExtras::QOhosAppContext::isNoUiChildMode()''' to detect this state.
* Use '''QtOhosExtras::QOhosAppContext::isNoUiChildMode()''' to detect this state.
* Do not attempt to create or manipulate windows/UI elements in this mode.
* Do not attempt to create or manipulate windows/UI elements in this mode.
'''Reference:''' [https://wiki.qt.io/Qt_for_HarmonyOS/user_development_guide/how_to_start_uiless_child_process How to start UIless child process]


== QProcess ==
== QProcess ==
Line 71: Line 76:
* Explicitly set a parent or '''transientParent'''.
* Explicitly set a parent or '''transientParent'''.
* Do not design these as completely independent top-level windows.
* Do not design these as completely independent top-level windows.
'''Reference:''' [[Qt_for_HarmonyOS/user_development_guide/mainwindow_and_subwindow_guide|mainwindow and subwindow]]


=== setParent() / Reparenting ===
=== setParent() / Reparenting ===
Line 79: Line 86:
* Verify the window path before re-parenting.
* Verify the window path before re-parenting.


== Modality and Window States ==
'''Reference:''' [[Qt_for_HarmonyOS/user_development_guide/embedded_subwindow_guide|embedded subwindow guide]]
 
== Modality, Minimization, Fullscreen, and Window States ==


=== Qt::WindowModality ===
=== Qt::WindowModality ===
* '''Modality''' is primarily effective in sub-window scenarios.
On desktop platforms, '''Qt::WindowModal''' and '''Qt::ApplicationModal''' typically have clear and complete modal semantics.
* '''Qt::ApplicationModal''' does not have the same global application-level scope as on desktop. Currently, it is only meaningful for sub-windows and is typically supported only on 2-in-1 or multi-window devices.
 
On the HarmonyOS platform:
* Modality is primarily designed for '''sub-window''' scenarios.
* '''Qt::ApplicationModal''' should not be simply understood as the same global application-level modality as seen on desktops. In the current implementation, it is only meaningful for sub-window scenarios and is only available on devices supporting free multi-window or 2-in-1 devices.
 
'''Recommendations:'''
* Prioritize designing application behavior based on sub-window modality.
* Do not rely on global application-level modality in the traditional desktop sense.
 
'''Reference:''' [https://developer.huawei.com/consumer/en/doc/harmonyos-references/arkts-apis-window-e#modalitytype14 HarmonyOS ModalityType API]


=== showFullScreen() / Qt::WindowFullScreen ===
=== showFullScreen() / Qt::WindowFullScreen ===
'''showFullScreen()''' is supported. For the initial main window, "fullscreen-on-startup" (via flags) is not supported because it often utilizes a platform-pre-created window path. Subsequent windows created by the app ''do'' support startup-fullscreen via flags.
On desktop platforms, '''showFullScreen()''' toggles a window to a fullscreen state.  
 
On the HarmonyOS platform, '''showFullScreen()''' is supported. When called at runtime, Qt switches the main window to the corresponding HarmonyOS fullscreen path and supports subsequent restoration to other window states.
 
For new main windows created by Qt, if '''Qt::WindowFullScreen''' is set before creation, Qt passes the fullscreen mode as a startup parameter to HarmonyOS.
 
'''Note:''' The creation path of the '''first main window''' differs from subsequent windows. The first main window may follow a platform-automated path for an existing window, meaning it does not support "fullscreen on startup." Subsequent new main windows do support this feature.


'''Recommendations:'''
'''Recommendations:'''
* For the first main window, call '''showFullScreen()''' after the window is created/shown to ensure stability.
* Do not treat the first main window and subsequent new main windows as identical fullscreen startup scenarios.
* For stable fullscreen behavior, call '''showFullScreen()''' or set '''Qt::WindowFullScreen''' after the window has been created and displayed.
 
'''Reference:''' [https://wiki.qt.io/Qt_for_HarmonyOS/user_development_guide/qt_for_harmonyos_fullscreen_main_window Fullscreen Guide]


=== showMinimized() / Qt::WindowMinimized ===
=== showMinimized() / Qt::WindowMinimized ===
* '''Main Windows:''' Support minimization semantics.
On other platforms, minimization is a standard top-level window capability.
* '''Sub-windows:''' Do not support minimization behavior consistent with desktop platforms.
 
On the HarmonyOS platform:
* '''Main windows''' support minimization semantics.
* '''Sub-windows''' do not support minimization behavior consistent with desktop platforms.
 
'''Recommendations:'''
* Limit minimization capabilities to main windows only.
* Do not design interaction logic for sub-windows that depends on a minimized state.


=== hide() ===
=== hide() ===
On HarmonyOS, '''hide()''' is not a universal window capability.
On desktop platforms, '''hide()''' is a general window hiding capability.
* For '''Main Windows''': It attempts system-level hiding (only supported if a tray exists), otherwise falls back to minimization.  
 
* For '''Sub-windows/Floating Windows''': It hides the window but lacks system-level "hide" semantics.
On the HarmonyOS platform, '''hide()''' is not a universal window capability:
* For '''Main Windows''': '''hide()''' prioritizes system-level hiding (only supported for windows with a system tray); if the system does not support it, it falls back to minimization.
* For '''Sub-windows and Floating Windows''': '''hide()''' hides the current window but does not carry the system-level "hide" semantics of a main window.


'''Recommendations:'''
'''Recommendations:'''
* Do not use '''hide()''' as a universal "close replacement" in '''closeEvent()'''.
* Do not use '''hide()''' as a universal "close replacement" in '''QWidget::closeEvent()'''.
* Use '''showMinimized()''' for main window persistence scenarios.
* For main window persistence (keeping the app alive), prioritize '''showMinimized()'''.
* Do not interpret '''hide()''' for sub-windows and floating windows using main window hiding semantics.


== Window Hints and Decorations ==
== Window Flags and Title Bar Capabilities ==


=== Minimize, Maximize, and Close Buttons ===
=== Qt::WindowMinimizeButtonHint, Qt::WindowMaximizeButtonHint, Qt::WindowCloseButtonHint ===
Hints like '''Qt::WindowMinimizeButtonHint''' are:
On other platforms, these flags control the visibility of title bar buttons.
* Primarily targeted at Main Windows.
 
On the HarmonyOS platform, these are not effective for all window types:
* Primarily targeted at '''main windows'''.
* Usually only meaningful in '''PC mode'''.
* Usually only meaningful in '''PC mode'''.
* Not guaranteed to work on all device types.
* Sub-windows are not guaranteed to behave consistently with other platforms.
 
'''Recommendations:'''
* Do not treat these flags as stable capabilities across different devices or window types.
* Design your UI to allow for these hints to not take effect.


=== Qt::FramelessWindowHint ===
=== Qt::FramelessWindowHint ===
On HarmonyOS, this flag hides system decorations. Note that for main windows, this also makes standard title bar buttons (Min/Max/Close) unavailable.
On the HarmonyOS platform, '''Qt::FramelessWindowHint''' primarily affects main and sub-windows by hiding system decorations. For main windows, enabling this flag also makes the standard three buttons (Min/Max/Close) unavailable.
 
'''Recommendations:'''
* After using this flag, do not assume title bar button capabilities will remain consistent with other platforms.


=== Qt::WindowStaysOnTopHint ===
=== Qt::WindowStaysOnTopHint ===
This capability is strictly limited:
On the HarmonyOS platform, this capability has stricter platform constraints:
* Primarily for Main Windows.
* Primarily targeted at '''main windows'''.
* Usually only effective in '''PC mode'''.
* Usually only effective in '''PC mode'''.


== Window Shapes and Persistence ==
'''Recommendations:'''
* Consider this capability only for main window scenarios.
* Do not assume it will be effective for sub-windows.
 
== Window Shape and Clipping ==


=== setMask() ===
=== setMask() ===
'''setMask()''' is only supported for '''sub-windows'''. It does not work on Main Windows. For main window shaped-looks, use content-level clipping or custom painting.
On desktop platforms, '''setMask()''' is used for non-rectangular windows or regional clipping.


=== Window Geometry Persistence ===
On the HarmonyOS platform, '''setMask()''' only works for '''sub-windows''' and is not supported for main windows.
Unlike '''QSettings''' on desktop, HarmonyOS window persistence relies on system capabilities. Use '''QtOhosExtras::setMainWindowGeometryPersistenceHint()'''.
* Must be called '''before''' the first main window is shown.
* Currently only supported on '''2-in-1''' devices.


== Close Semantics and Drag & Drop ==
'''Recommendations:'''
* Do not use '''setMask()''' for main window irregular clipping.
* To achieve a special appearance for the main window, use content-level clipping or custom drawing solutions.
 
== Window Geometry Persistence ==
Unlike other platforms where apps save window positions via '''QSettings''', HarmonyOS window memory relies on system window management capabilities. Qt provides an interface via '''QtOhosExtras::setMainWindowGeometryPersistenceHint()'''.
 
* This capability currently targets the '''first main window only'''.
* It must be set '''before''' the first main window is displayed; calling it afterward will not update the persistence strategy.
* Currently only supported on '''2-in-1 devices'''.
 
== Window Close Semantics ==


=== closeEvent(QCloseEvent *) ===
=== closeEvent(QCloseEvent *) ===
A '''closeEvent''' may originate from a user action or the system's Ability lifecycle termination.
On the HarmonyOS platform, a close event may come from a window closing action or a system '''Ability lifecycle termination'''.
* '''Recommendation:''' Distinguish between UI window closing and lifecycle-driven termination in your design.
 
'''Recommendations:'''
* Do not treat all '''closeEvent()''' calls as "user clicked the close button."
* Distinguish between window closing and lifecycle termination in your application design.
 
'''Reference:''' [https://wiki.qt.io/Qt_for_HarmonyOS/user_development_guide/application_lifecycle_guide#%E5%BA%94%E7%94%A8%E9%80%80%E5%87%BA Application Exit Guide]
 
== Drag and Drop Data Access ==


=== Drag and Drop Data Access ===
On the HarmonyOS platform, for drag operations from external sources:
* '''dragEnterEvent / dragMoveEvent:''' Usually only MIME type information is available. Actual data content cannot be accessed at this stage.
* During '''dragEnterEvent''' and '''dragMoveEvent''', the application can usually only obtain MIME type information; the actual '''QMimeData''' content is inaccessible.
* '''dropEvent:''' This is the only stage where the actual '''QMimeData''' content is provided to the application.
* Only when a '''dropEvent''' occurs is the real drag data converted into '''QMimeData''' and provided to the Qt application.


'''Recommendations:'''
'''Recommendations:'''
* Do not rely on actual data content for validation during "Enter" or "Move" phases.
* Do not rely on actual data content for validation in '''dragEnterEvent''' or '''dragMoveEvent'''.
* Use MIME types to decide acceptance and read the data only in '''dropEvent'''.
* Use MIME types to decide whether to accept a drag during the enter/move phases.
* Process and read actual data content only within the '''dropEvent'''.


== Summary of Known Principles ==
== Known Usage Principles ==
Avoid applying desktop experiences directly to the following on HarmonyOS:
On the HarmonyOS platform, the following capabilities should not be used based strictly on desktop experience:
* Minimizing sub-windows.
* Minimization of sub-windows.
* Desktop-style global application modality.
* Desktop-style global application modality.
* Uniform title bar button support across all window types.
* Consistent title bar button control across all windows.
* Universal "Stay on Top" support.
* Uniform "Stay on Top" support for all windows.
* Main window masking/clipping via '''setMask()'''.
* Irregular main window clipping using '''setMask()'''.
* Treating external embedded windows as standard Qt top-level windows.
* Treating external embedded windows as standard Qt top-level windows.

Latest revision as of 09:50, 11 May 2026

English 中文

Qt for HarmonyOS: API Compatibility and Porting Notes

This document outlines the key differences and limitations when using Qt public APIs on the HarmonyOS platform compared to other common platforms such as Windows, Linux, macOS, and Android.

The focus of this guide is on behavioral differences that affect application development and cross-platform porting, rather than internal implementation details.

Application Startup and Argument Passing

main(int argc, char *argv[])

On traditional platforms, argv[0] typically represents the executable path, and business arguments start from argv[1].

On HarmonyOS, the source and splicing of startup arguments differ:

  • argv[0] represents the application library path, not a traditional executable file path.
  • When passing arguments via a Want, the want.uri may occupy argv[1] by default.
  • Consequently, the index of business arguments in argv may vary compared to other platforms.

Recommendations:

  • Do not assume business arguments fixedly start at argv[1].
  • Parse arguments based on the actual content of argc/argv.

Reference: Passing Arguments to main

Launching Application Instances or Processes

On desktop platforms, applications usually start another process via an executable path. On HarmonyOS, this depends on the system's Ability/Want/Process management mechanism. Qt for HarmonyOS capabilities are centered around "Starting an Ability" or "Starting an App Instance" rather than "Running an arbitrary external program."

Key public interfaces include:

  • QtOhosExtras::startAbility()
  • QtOhosExtras::startNewAbilityInstance()
  • QtOhosExtras::startAppProcess()

Recommendations:

  • Avoid the desktop mindset of "providing a path to launch a process."
  • Use Ability/Want interfaces for cross-instance or cross-process activation.

Reference: Application Lifecycle Guide

UI-less Child Processes

Qt provides a dedicated "UI-less child process" capability via: QtOhosExtras::QOhosAppContext::startNoUiChildProcess(). This uses the HarmonyOS Child Process Manager. Arguments are forwarded to the child's main().

Once started, the process enters a specialized NoUiChildProcess mode. In this mode, certain Qt platform capabilities are restricted (e.g., UI rendering pipelines are not initialized).

Recommendations:

  • UI-less processes should be used strictly for computation, background tasks, or auxiliary processing.
  • Use QtOhosExtras::QOhosAppContext::isNoUiChildMode() to detect this state.
  • Do not attempt to create or manipulate windows/UI elements in this mode.

Reference: How to start UIless child process

QProcess

On desktop, QProcess is a universal interface for external programs. On HarmonyOS, the process model is different. The explicitly supported path for Qt child processes is startNoUiChildProcess(), not QProcess.

Do not assume QProcess behaves identically to desktop platforms regarding:

  • Launching arbitrary external executables.
  • Launching independent GUI child processes.
  • Standard start(), startDetached(), or execute() semantics.

Recommendations:

  • Do not treat QProcess as the recommended solution for launching child processes on HarmonyOS.
  • Use startNoUiChildProcess() for background tasks and startAbility() for independent UI instances.

Window Types and Relationships

QDialog, Qt::Popup, Qt::ToolTip, Qt::Tool

On desktop, these are often treated as independent top-level windows. On HarmonyOS, they behave more like sub-windows attached to a main window:

  • Parent-child relationships are strictly enforced.
  • Activation behavior depends on the main window.
  • Closing behavior is tied to the main window's lifecycle.

Recommendations:

  • Explicitly set a parent or transientParent.
  • Do not design these as completely independent top-level windows.

Reference: mainwindow and subwindow

setParent() / Reparenting

HarmonyOS imposes additional restrictions on adjusting parent-child relationships, especially regarding embedded or external windows.

Recommendations:

  • Do not treat external embedded windows as standard parent windows.
  • Verify the window path before re-parenting.

Reference: embedded subwindow guide

Modality, Minimization, Fullscreen, and Window States

Qt::WindowModality

On desktop platforms, Qt::WindowModal and Qt::ApplicationModal typically have clear and complete modal semantics.

On the HarmonyOS platform:

  • Modality is primarily designed for sub-window scenarios.
  • Qt::ApplicationModal should not be simply understood as the same global application-level modality as seen on desktops. In the current implementation, it is only meaningful for sub-window scenarios and is only available on devices supporting free multi-window or 2-in-1 devices.

Recommendations:

  • Prioritize designing application behavior based on sub-window modality.
  • Do not rely on global application-level modality in the traditional desktop sense.

Reference: HarmonyOS ModalityType API

showFullScreen() / Qt::WindowFullScreen

On desktop platforms, showFullScreen() toggles a window to a fullscreen state.

On the HarmonyOS platform, showFullScreen() is supported. When called at runtime, Qt switches the main window to the corresponding HarmonyOS fullscreen path and supports subsequent restoration to other window states.

For new main windows created by Qt, if Qt::WindowFullScreen is set before creation, Qt passes the fullscreen mode as a startup parameter to HarmonyOS.

Note: The creation path of the first main window differs from subsequent windows. The first main window may follow a platform-automated path for an existing window, meaning it does not support "fullscreen on startup." Subsequent new main windows do support this feature.

Recommendations:

  • Do not treat the first main window and subsequent new main windows as identical fullscreen startup scenarios.
  • For stable fullscreen behavior, call showFullScreen() or set Qt::WindowFullScreen after the window has been created and displayed.

Reference: Fullscreen Guide

showMinimized() / Qt::WindowMinimized

On other platforms, minimization is a standard top-level window capability.

On the HarmonyOS platform:

  • Main windows support minimization semantics.
  • Sub-windows do not support minimization behavior consistent with desktop platforms.

Recommendations:

  • Limit minimization capabilities to main windows only.
  • Do not design interaction logic for sub-windows that depends on a minimized state.

hide()

On desktop platforms, hide() is a general window hiding capability.

On the HarmonyOS platform, hide() is not a universal window capability:

  • For Main Windows: hide() prioritizes system-level hiding (only supported for windows with a system tray); if the system does not support it, it falls back to minimization.
  • For Sub-windows and Floating Windows: hide() hides the current window but does not carry the system-level "hide" semantics of a main window.

Recommendations:

  • Do not use hide() as a universal "close replacement" in QWidget::closeEvent().
  • For main window persistence (keeping the app alive), prioritize showMinimized().
  • Do not interpret hide() for sub-windows and floating windows using main window hiding semantics.

Window Flags and Title Bar Capabilities

Qt::WindowMinimizeButtonHint, Qt::WindowMaximizeButtonHint, Qt::WindowCloseButtonHint

On other platforms, these flags control the visibility of title bar buttons.

On the HarmonyOS platform, these are not effective for all window types:

  • Primarily targeted at main windows.
  • Usually only meaningful in PC mode.
  • Sub-windows are not guaranteed to behave consistently with other platforms.

Recommendations:

  • Do not treat these flags as stable capabilities across different devices or window types.
  • Design your UI to allow for these hints to not take effect.

Qt::FramelessWindowHint

On the HarmonyOS platform, Qt::FramelessWindowHint primarily affects main and sub-windows by hiding system decorations. For main windows, enabling this flag also makes the standard three buttons (Min/Max/Close) unavailable.

Recommendations:

  • After using this flag, do not assume title bar button capabilities will remain consistent with other platforms.

Qt::WindowStaysOnTopHint

On the HarmonyOS platform, this capability has stricter platform constraints:

  • Primarily targeted at main windows.
  • Usually only effective in PC mode.

Recommendations:

  • Consider this capability only for main window scenarios.
  • Do not assume it will be effective for sub-windows.

Window Shape and Clipping

setMask()

On desktop platforms, setMask() is used for non-rectangular windows or regional clipping.

On the HarmonyOS platform, setMask() only works for sub-windows and is not supported for main windows.

Recommendations:

  • Do not use setMask() for main window irregular clipping.
  • To achieve a special appearance for the main window, use content-level clipping or custom drawing solutions.

Window Geometry Persistence

Unlike other platforms where apps save window positions via QSettings, HarmonyOS window memory relies on system window management capabilities. Qt provides an interface via QtOhosExtras::setMainWindowGeometryPersistenceHint().

  • This capability currently targets the first main window only.
  • It must be set before the first main window is displayed; calling it afterward will not update the persistence strategy.
  • Currently only supported on 2-in-1 devices.

Window Close Semantics

closeEvent(QCloseEvent *)

On the HarmonyOS platform, a close event may come from a window closing action or a system Ability lifecycle termination.

Recommendations:

  • Do not treat all closeEvent() calls as "user clicked the close button."
  • Distinguish between window closing and lifecycle termination in your application design.

Reference: Application Exit Guide

Drag and Drop Data Access

On the HarmonyOS platform, for drag operations from external sources:

  • During dragEnterEvent and dragMoveEvent, the application can usually only obtain MIME type information; the actual QMimeData content is inaccessible.
  • Only when a dropEvent occurs is the real drag data converted into QMimeData and provided to the Qt application.

Recommendations:

  • Do not rely on actual data content for validation in dragEnterEvent or dragMoveEvent.
  • Use MIME types to decide whether to accept a drag during the enter/move phases.
  • Process and read actual data content only within the dropEvent.

Known Usage Principles

On the HarmonyOS platform, the following capabilities should not be used based strictly on desktop experience:

  • Minimization of sub-windows.
  • Desktop-style global application modality.
  • Consistent title bar button control across all windows.
  • Uniform "Stay on Top" support for all windows.
  • Irregular main window clipping using setMask().
  • Treating external embedded windows as standard Qt top-level windows.