From a193e59eebcaab22fd390339a13a83b2b5d0e947 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Wed, 20 Dec 2023 13:59:03 +0100 Subject: Document how to write and use QML modules The application-features example has been enhanced with QML modules. This adds the missing documentation. Change-Id: I8e04f66f63ab057b904f3a0436d0a84eba261620 Pick-to: 6.7 Reviewed-by: Nicholas Bennett Reviewed-by: Robert Griebl --- doc/resources.qdoc | 17 +++-- .../application-features/SystemUi/CMakeLists.txt | 1 - .../application-features/am-config.yaml | 1 - .../application-features/apps/Crash/CMakeLists.txt | 1 - .../apps/Crash/Sequel/CMakeLists.txt | 1 - .../doc/src/application-features.qdoc | 78 +++++++++++++++++++--- 6 files changed, 80 insertions(+), 19 deletions(-) diff --git a/doc/resources.qdoc b/doc/resources.qdoc index 9e3ca1c8..19183fd7 100644 --- a/doc/resources.qdoc +++ b/doc/resources.qdoc @@ -21,7 +21,7 @@ multi-process modes. \section1 Compiling Resources You can add resources as \l{External Resource Files}{external binary resources} or as -\l{Resource Collection Files}{compiled-in resources}; both are generated from a \c .qrc file. +\l{Resource Collection Files}{compiled-in resources}; both can be generated from a \c .qrc file. Typically, external binary resources are stored in a file with the \c .rcc extension, whereas compiled-in resources are stored in libraries in the Application Manager context. @@ -60,6 +60,15 @@ For \c grandtheftdolphin the prefix should be "grandtheftdolphin", respectively. Generally, all files contained in any \c .qrc file should be unique; this also includes files that the System UI uses. +The same applies when resources are added directly, without a \c .qrc file, for instance when +defining a QML module, \c RESOURCE_PREFIX should be set: +\badcode +qt_add_qml_module(spaceinvaders + URI "SpaceInvaders" + RESOURCE_PREFIX spaceinvaders + QML_FILES main.qml +) +\endcode \section1 Loading Resources @@ -73,11 +82,11 @@ into the System UI by adding the following lines to the \c am-config.yaml file: \badcode ui: resources: [ "${CONFIG_PWD}/my.rcc", - "${CONFIG_PWD}/myplugin.so" ] + "${CONFIG_PWD}/myplugin" ] \endcode -You can also load these two files into an application by adding the following snippet to the -\c info.yaml file: +As you can see, the library file extension can be omitted. You can also load these two files into +an application by adding the following snippet to the \c info.yaml file: \badcode runtimeParameters: diff --git a/examples/applicationmanager/application-features/SystemUi/CMakeLists.txt b/examples/applicationmanager/application-features/SystemUi/CMakeLists.txt index 90f5e188..436a212e 100644 --- a/examples/applicationmanager/application-features/SystemUi/CMakeLists.txt +++ b/examples/applicationmanager/application-features/SystemUi/CMakeLists.txt @@ -2,7 +2,6 @@ qt_policy(SET QTP0001 NEW) # "qt/qml/" default resource prefix qt6_add_qml_module( systemuimodule - VERSION 1.0 URI "SystemUi" NO_PLUGIN RESOURCES grab.png close.png diff --git a/examples/applicationmanager/application-features/am-config.yaml b/examples/applicationmanager/application-features/am-config.yaml index f1c110b9..5e986ca3 100644 --- a/examples/applicationmanager/application-features/am-config.yaml +++ b/examples/applicationmanager/application-features/am-config.yaml @@ -15,7 +15,6 @@ logging: - "*.critical=true" ui: - fullscreen: no mainQml: ":/qt/qml/SystemUi/main.qml" resources: [ "${CONFIG_PWD}/SystemUi/libsystemuimodule" ] diff --git a/examples/applicationmanager/application-features/apps/Crash/CMakeLists.txt b/examples/applicationmanager/application-features/apps/Crash/CMakeLists.txt index fd9bdd4b..0fc5656b 100644 --- a/examples/applicationmanager/application-features/apps/Crash/CMakeLists.txt +++ b/examples/applicationmanager/application-features/apps/Crash/CMakeLists.txt @@ -7,7 +7,6 @@ qt_standard_project_setup() qt6_add_qml_module( crashmodule - VERSION 1.0 URI "Crash" NO_PLUGIN SOURCES terminator1.cpp diff --git a/examples/applicationmanager/application-features/apps/Crash/Sequel/CMakeLists.txt b/examples/applicationmanager/application-features/apps/Crash/Sequel/CMakeLists.txt index e1b414d1..e21caee7 100644 --- a/examples/applicationmanager/application-features/apps/Crash/Sequel/CMakeLists.txt +++ b/examples/applicationmanager/application-features/apps/Crash/Sequel/CMakeLists.txt @@ -1,6 +1,5 @@ qt6_add_qml_module( sequelmoduleplugin - VERSION 1.0 URI "Sequel" PLUGIN_TARGET sequelmoduleplugin SOURCES terminator2.cpp diff --git a/examples/applicationmanager/application-features/doc/src/application-features.qdoc b/examples/applicationmanager/application-features/doc/src/application-features.qdoc index b084e79d..cc9fe3e1 100644 --- a/examples/applicationmanager/application-features/doc/src/application-features.qdoc +++ b/examples/applicationmanager/application-features/doc/src/application-features.qdoc @@ -7,7 +7,7 @@ \example applicationmanager/application-features \title Application Features Example \image application-features.png -\brief Showcases client applications with various features, including a native application. +\brief Showcases client applications with various features and QML modularization. \ingroup applicationmanager-examples \section1 Introduction @@ -26,10 +26,13 @@ application, such as: Most of these features are only supported properly in \l{Single-Process vs. Multi-Process Mode}{multi-process mode}. -\note This example focuses on the application (client) side. The \l{The System UI}{System UI} +The example focuses on the application (client) side. The \l{The System UI}{System UI} (compositor/server) is based on the \l{Desktop System UI Example} with some modifications. Refer to that example for more details on how to implement a System UI. +In addition, this example shows how to write and use \l{Writing QML Modules}{QML modules} in the +application manager context, see \l{Code Structure}{below}. + \section2 Nested Compositor The nested compositor application shows how to implement a Wayland compositor inside an application @@ -55,13 +58,11 @@ The QML code for the nested compositor application is as follows: \section2 Crash Simulation and Recovery This application provides various means to force a crash in an application, such as a segmentation -fault. It utilizes a QML plugin implemented in C++, to provide the \c Terminator QML type to -trigger crashes. The application manager then prints the cause of the crash and related -information, like a backtrace. The System UI implements a basic form of crash recovery: restarting -the application. - -This application only works on multi-process mode. In single-process mode a crash affects the entire -program (the System UI). +fault. It utilizes QML modules that include C++ and QML code; in particular, the C++ provided QML +types \c Terminator1 and \c Terminator2 are used to trigger crashes. The application manager then +prints the cause of the crash and related information, like a backtrace. The System UI implements a +basic form of crash recovery: restarting the application. Of course, crash recovery only works in +multi-process mode. In single-process mode, a crash affects the entire program (the System UI). The QML code for the crash simulation and recovery application is as follows: @@ -114,6 +115,61 @@ requires you to build it explicitly. The code is structured in a way where the r folders only contain the artifacts necessary to run the application. Consequently, you can package these applications and install them as well. -To build Qt Application Manager including its examples, you need to pass \c qmake the -\c{-config enable-examples} parameter For more details, see \l{build}{Build}. +To build Qt Application Manager, including its examples, you need to pass +\c{-DQT_BUILD_EXAMPLES=ON} to CMake. For more details, see \l{build}{Build}. + +The System UI and the Crash application produce QML modules. These modules are generated as +libraries that include all the C++ and QML code and other resources, like images. Consequently, +only the libraries need to be loaded from the native file system instead of individual QML files, +images, or other such assets. As an additional bonus, you get things like pre-compiled QML, linting +checks, and auto-generation of files like qmldir. + +\section2 System UI QML Module + +In the \c{SystemUi/CMakeLists.txt} file, the \c systemuimodule is defined: +\quotefromfile applicationmanager/application-features/SystemUi/CMakeLists.txt +\printuntil /^\)$/ + +The default "qt/qml" resource prefix is used here. By providing the \c NO_PLUGIN keyword, only a +dynamic backing library is created. A QML plugin is unnecessary since the library will be loaded +explicitly (see below). To keep it simple, the module is kept in a directory with the same name as +its URI (\c SystemUi). Two images and the \c main.qml file is added to the module (there is no C++ +code used, though). + +The \c systemuimodule dynamic library is added to the list of resources that are loaded at startup +in the \c am-config.yaml file (key \c{ui/resources}): +\quotefromfile applicationmanager/application-features/am-config.yaml +\skipto ui: +\printuntil resources: +The library is loaded from the native file system, but the \c main.qml file can subsequently be +loaded from the resource file system (key \c{ui/mainQml}). The path starts with the resource +prefix, extended with the module URI. Since the images used in \c main.qml have relative URLs they +are also found in the resource file system. + +A general overview how to add and use resources in the application manager context can be found in +\l{Using Qt Resources}. + +\section2 Crash Application QML Modules + +The Crash application consists of two QML modules: \c crashmodule and \c sequelmoduleplugin. The +first is analogous to the \c systemuimodule above, except that it also includes C++ code +(\c terminator1.cpp). The generated library is loaded explicitly when the application starts +through the following lines in \c{apps/Crash/info.yaml}: +\quotefromfile applicationmanager/application-features/apps/Crash/info.yaml +\skipto runtimeParameters: +\printuntil resources: + +It provides the \c crashapp.qml file, which is the application's main QML file and the +\c Terminator1 QML singleton type. + +The second module, \c sequelmoduleplugin is defined as a QML plugin in +\c{apps/Crash/Sequel/CMakeLists.txt}: +\quotefromfile applicationmanager/application-features/apps/Crash/Sequel/CMakeLists.txt +\printuntil /^\)$/ +For convenience, \c PLUGIN_TARGET is defined with the same argument as the module target name. +This creates a plugin that already includes the backing target (see +\l{Plugin target with no backing target}{qt_add_qml_module}). The plugin is loaded implicitly +at runtime through the "\c{import Sequel}" statement in \c crashapp.qml. It provides the +\c CrashAnimation and \c Terminator2 QML types. + */ -- cgit v1.2.3