Qt for HarmonyOS/user development guide/mainwindow and subwindow guide: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
Line 128: Line 128:
==== 5.3 Multi-window Application Example ====  
==== 5.3 Multi-window Application Example ====  
<syntaxhighlight lang="c++">  
<syntaxhighlight lang="c++">  
class MainWindow : public QMainWindow
class MainWindow : public QMainWindow
{
{

Revision as of 06:22, 29 July 2025

English 中文 == Main Window and Subwindow Development Guide for Qt on HarmonyOS ==

1. Concepts of Main Window and Subwindow

1.1 Main Window and Subwindow in HarmonyOS

Main Window: Represents a "task" window, has a Dock icon and a task icon (visible in Alt+Tab task switcher), generally has an independent lifecycle, and can be maximized, minimized, or windowed.

Subwindow: An independent window created for a sub-feature of a task, displayed outside the main window but without a Dock icon or task icon. It must belong to a main window. When the main window closes, the subwindow closes automatically; when the main window is minimized, the subwindow hides; when the main window is restored, the subwindow is shown again. On HarmonyOS, subwindows typically correspond to popups and dialogs.

1.2 Creating Qt Widgets or Windows

Qt does not natively distinguish between main and subwindows when creating widgets or windows (some widgets like QDialog have a Transient Parent concept, which is similar to the main/subwindow relationship in HarmonyOS).

Example:

 

// Independent window QWidget w; 
w.show();

// Window with parent-child relationship (assuming wp is associated with a native window) 
QWidget wp; 
wp.show(); 
QWidget w(&wp);

// Dialog 
QDialog dlg; 
dlg.exec();

// Dialog with a parent window (Transient Parent) 
QWidget w; 
w.show(); 
QDialog dlg(&w); 
dlg.exec();

2. HarmonyOS Adaptation Rules

2.1 Core Rules

  • Tagging function: Use QOhosFunctions::tagWindowOrWidgetAsSubWindowOf(QObject *windowOrWidgetToTag, QWindow *mainWindow) to instruct Qt to create a HarmonyOS subwindow for the specified top-level window, and specify its parent window. This function must be called after the main window is created and before the subwindow is created.
  • First window rule: The first QWindow (or a QWidget without a parent) created in the process will automatically be bound to the system's first main window for the application.
  • Subsequent windows rule: Any non-first QWindow (or QWidget without a parent) that is created without the AsSubWindowOf tag will be created as a HarmonyOS main window.
  • Transient Parent handling: For Qt widgets that natively support the Transient Parent concept (such as QDialog), if a Transient Parent is provided, the main window will be the one associated with the Transient Parent; if not, the main window is determined as with ordinary widgets.
  • Automatic Fallback mechanism: If the tagged parent window is invalid, the system will automatically find a suitable parent window for certain types (such as Qt::Popup, Qt::ToolTip, Qt::Dialog, Qt::Tool):
    • Prefer the currently focused window
    • Otherwise, use the first available top-level window
    • Ensure every window finds a suitable parent

2.2 Development Recommendations

Developers should understand the main/subwindow concept in HarmonyOS. When creating a new top-level Widget (without a parent) in Qt, if it should be a HarmonyOS subwindow, call QOhosFunctions::tagWindowOrWidgetAsSubWindowOf() and specify its parent window.

Typical scenarios:

  • Single-instance application: If your app has a single main window, call the AsSubWindowOf tag when creating subwindows.
  • Multi-instance application: If your app supports multiple main windows in a single process, and all subwindows are triggered by user actions, call the AsSubWindowOf tag for subwindows. Creating a new main window requires no special handling.
  • Transient Parent windows: For QDialogs or similar widgets that support Transient Parent and are constructed with a parent, you do not need to call the AsSubWindowOf tag—default behavior is sufficient.

3. API Reference

3.1 Main Function

 
static void QOhosFunctions::tagWindowOrWidgetAsSubWindowOf(QObject *windowOrWidgetToTag, QWindow *mainWindow)

This function sets a hint for the window system so that the given QWindow or QWidget is instantiated as a subwindow of the specified main window, not as a main window.

Parameter Description:

  • windowOrWidgetToTag: The QObject (must be a QWindow or QWidget) to be tagged as a subwindow
  • mainWindow: The designated parent main window

3.2 Auxiliary Functions

 // Tag a window as a main window

static void QOhosFunctions::tagWindowOrWidgetAsMainWindow(QObject *windowOrWidgetToTag, bool forceMainWindow = true)

// Get the parent window pointer tagged by tagWindowOrWidgetAsSubWindowOf

static QWindow *QOhosFunctions::getWindowOrWidgetAsSubWindowOfTagValue(QObject *targetWindowOrWidget)

4. Important Notes

⚠️ Warning:

  • Calling winId() or show() before tagging will invalidate the tag.
  • mainWindow must be a valid QWindow pointer.
  • If mainWindow points to a valid QWindow but it is not a main window, Qt will use the automatic fallback mechanism to find a suitable main window. If none is found, a main window will be created instead of a subwindow.

5. Code Examples

5.1 Basic Usage

 

#include <QtPlatformHeaders/QOhosFunctions>

// Create a subwindow and specify its parent main window

m_subwindow = new QWidget();

QOhosFunctions::tagWindowOrWidgetAsSubWindowOf(m_subwindow, this->windowHandle());

m_subwindow->resize(800, 600);

m_subwindow->show();

5.2 Dialog Example

 

// Method 1: Use Transient Parent (recommended)

QDialog *dialog = new QDialog(this); // 'this' is the main window widget

dialog->exec(); // No extra tagging needed


// Method 2: Manual tagging

QDialog *dialog = new QDialog();

QOhosFunctions::tagWindowOrWidgetAsSubWindowOf(dialog, this->windowHandle());

dialog->exec();

5.3 Multi-window Application Example

 
class MainWindow : public QMainWindow
{
public:
    void createSubWindow() {
        // Create a subwindow
        QWidget *subWindow = new QWidget();
        // Tag as a subwindow of the current main window
        QOhosFunctions::tagWindowOrWidgetAsSubWindowOf(subWindow, this->windowHandle());
        subWindow->setWindowTitle("Subwindow");
        subWindow->resize(400, 300);
        subWindow->show();
    }

    void createNewMainWindow() {
        // Create a new main window (no special tagging needed)
        MainWindow *newMainWindow = new MainWindow();
        newMainWindow->show();
    }
};

6. Best Practices

Tag in time: Always tag the window before calling show() or winId()

Classify properly: Clearly distinguish which windows should be main windows and which should be subwindows

Use Transient Parent: For dialogs and temporary windows, prefer Qt’s native parent mechanism

Test and verify: Check window hierarchy and lifecycle on HarmonyOS devices

Error handling: Consider fallback behavior when the parent window is invalid


7. FAQ

Q: Why does my subwindow appear as a main window?

A: Possible reasons:

  • Tagging function was called after show().
  • The mainWindow parameter is invalid.
  • Forgot to call the tagging function.

Q: Can a subwindow exist independently of the main window?

A: No. On HarmonyOS, subwindows must be attached to a main window. When the main window closes, the subwindow closes automatically.

Q: How can I check if the window parent-child relationship is correct?

A: Use QOhosFunctions::getWindowOrWidgetAsSubWindowOfTagValue() to query the tag status of a window.