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

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''English''' [[Qt_for_HarmonyOS/user_development_guide/mainwindow_and_subwindow_guide|中文]] == Main Window and Subwindow Development Guide for Qt on HarmonyOS ==
'''English''' [[Qt_for_HarmonyOS/user_development/mainwindow_and_subwindow_guide_zh|中文]]  
 
== Main Window and Subwindow Development Guide for Qt on HarmonyOS ==


=== 1. Concepts of Main Window and Subwindow ===
=== 1. Concepts of Main Window and Subwindow ===
Line 37: Line 39:
==== 2.1 Core 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.
* '''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


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.
==== 2.2 Development Recommendations ====


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.
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.
 
'''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
<nowiki>==== 2.2 Development Recommendations ====</nowiki>


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:'''


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.


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. API Reference ===


Line 68: Line 67:
'''Parameter Description''':
'''Parameter Description''':


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


==== 3.2 Auxiliary Functions ====  
==== 3.2 Auxiliary Functions ====  
Line 86: Line 85:
==== ⚠️ Warning: ====
==== ⚠️ Warning: ====


Calling winId() or show() before tagging will invalidate the tag.
* Calling winId() or show() before tagging will invalidate the tag.
mainWindow must be a valid QWindow pointer.
* 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.
* 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. Code Examples ===


==== 5.1 Basic Usage ==== <syntaxhighlight lang="c++"> #include <QtPlatformHeaders/QOhosFunctions>
==== 5.1 Basic Usage ====  
<syntaxhighlight lang="c++">  
 
#include <QtPlatformHeaders/QOhosFunctions>


// Create a subwindow and specify its parent main window
// Create a subwindow and specify its parent main window
Line 101: Line 104:
m_subwindow->resize(800, 600);
m_subwindow->resize(800, 600);


m_subwindow->show(); </syntaxhighlight>
m_subwindow->show();  


==== 5.2 Dialog Example ==== <syntaxhighlight lang="c++"> // Method 1: Use Transient Parent (recommended)
</syntaxhighlight>
 
==== 5.2 Dialog Example ====  
<syntaxhighlight lang="c++">  
 
// Method 1: Use Transient Parent (recommended)


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


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


// Method 2: Manual tagging
// Method 2: Manual tagging
Line 115: Line 124:
QOhosFunctions::tagWindowOrWidgetAsSubWindowOf(dialog, this->windowHandle());
QOhosFunctions::tagWindowOrWidgetAsSubWindowOf(dialog, this->windowHandle());


dialog->exec(); </syntaxhighlight>
dialog->exec();  


==== 5.3 Multi-window Application Example ==== <syntaxhighlight lang="c++"> class MainWindow : public QMainWindow
</syntaxhighlight>


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


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


=== 6. Best Practices ===
=== 6. Best Practices ===


'''Tag in time''': Always tag the window before calling '''show'''() or '''winId'''()
* '''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
'''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
'''Use Transient Parent''': For dialogs and temporary windows, prefer Qt’s native parent mechanism
* '''Error handling''': Consider fallback behavior when the parent window is invalid
 
'''Test and verify''': Check window hierarchy and lifecycle on HarmonyOS devices
 
'''Error handling''': Consider fallback behavior when the parent window is invalid
 
 
7. FAQ


=== 7. FAQ ===
'''Q: Why does my subwindow appear as a main window?'''
'''Q: Why does my subwindow appear as a main window?'''



Latest revision as of 06:24, 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.