System UI Example: "Hello World!"
Learn how to write your first System UI.
Note: Please read this if you want to build the example on a Linux machine.
Introduction
This example shows a very simple System UI implementation that showcases Qt Application Manager's fundamental building blocks.
The applications' icons and names are on the left. You can click on their respective icons to start and stop them. The column layout on the right shows their windows.
The applications display "Hello World!" against a background of a specific color.
Files and Folder Structure
This example comprises of four separate QML applications: a System UI and three sample applications: "Hello Red", "Hello Green" and "Hello Blue". The System UI is also a QML application, albeit a special one.
Each application is put in a separate directory as follows:
system-ui.qml
apps
hello-world.blue
icon.png
info.yaml
main.qml
hello-world.red
icon.png
info.yaml
main.qml
hello-world.green
icon.png
info.yaml
main.qml
Each application has a main.qml
file, an icon, and an info.yaml
. This YAML file contains application metadata such as the name of the application, its icon filename, and more.
Run the System UI
The compiled hello-world binary contains a complete application manager including the am-config.yaml
configuration file and the System UI QML files.
The screenshot below is what you should see when running the binary:
CMake integration and ApplicationManager configuration
As said above the example binary contains the QML files and the am-config.yaml
configuration file. This is done by adding all those files into the executable as follows in the CMakeLists.txt file:
qt_add_qml_module(hello-world URI SystemUI QML_FILES system-ui.qml RESOURCES am-config.yaml )
The am-config.yaml
file contains the configuration for the Application Manager. It specifies where the builtin applications can be found by setting applications/builtinAppsManifestDir
to "${EXECUTABLE_DIR}/apps"
. In addition the configuration file specifies the location of the main QML file by setting ui/mainQml
to "${CONFIG_DIR}/system-ui.qml"
.
For information on the contents of am-config.yaml
and other command line options you can run appman –help
or have a look at the Configuration documentation.
In addition to the System UI itself, the application packages also need to be added to our CMakeLists.txt file. This is done by adding the following lines:
qt_am_create_builtin_package(hello-world.blue OUTPUT_DIRECTORY apps/hello-world.blue INSTALL_DIRECTORY ${INSTALL_EXAMPLEDIR}/apps/hello-world.blue FILES apps/hello-world.blue/info.yaml apps/hello-world.blue/icon.png apps/hello-world.blue/main.qml )
Implement the System UI
Like any simple QML application, our example's code starts with some imports and a plain Item at the root. The only difference is that our System UI also imports the QtApplicationManager.SystemUI
module, besides QtQuick
.
import QtQuick import QtApplicationManager.SystemUI Item { width: 800 height: 600
Next, we have a Column on the left side of the root Item where we place the icons of the available applications along with their names.
// Show application names and icons Column { spacing: 20 Repeater { model: ApplicationManager Column { id: delegate required property bool isRunning required property var icon required property var application required property string name Image { source: delegate.icon MouseArea { anchors.fill: parent onClicked: delegate.isRunning ? delegate.application.stop() : delegate.application.start() } } Text { font.pixelSize: 20 text: delegate.name } } } }
We use the ApplicationManager
singleton, as a model, which provides a row for each application available. In each row, we have:
- an
icon
role with the icon URL - a
name
role with the localized application's name - a boolean
isRunning
that provides the application's status - an
application
role that contains its ApplicationObject
For information on the other roles available, see ApplicationManager QML Type.
Clicking on an icon either starts its application or stops it if it's already running.
Next, we place a Column
anchored to the right side of the root Item
. In this column, we lay out the existing windows for all applications that are currently running:
// Show windows Column { anchors.right: parent.right Repeater { model: WindowManager WindowItem { required property var model width: 600 height: 200 window: model.window } } }
This time, we use the WindowManager
singleton as the model. There's a row for each window, with its WindowObject in the window
role.
To have a window rendered in our System UI, we have to assign its WindowObject to a WindowItem, as we did above. By default, the window is resized to match the size of the WindowItem rendering it.
Implement the Application
Our Hello World applications display a "Hello World!" text against a colored background.
import QtQuick import QtApplicationManager.Application ApplicationManagerWindow { color: "blue" Text { anchors.centerIn: parent text: "Hello World!" } }
The only difference between this example and a plain QML application is that the root element is an ApplicationManagerWindow, provided by the QtApplicationManager.Application
module.
Application Metadata
The info.yaml
file contains the metadata about an application. It starts with some boilerplate describing that this file contains Qt Application Manager package metadata.
formatVersion: 1 formatType: am-package ---
Then comes the package ID, which uniquely identifies the package. It's recommended to follow a reverse DNS scheme, but it's not enforced. Here it's the "Blue" package from the "Hello World" example UI.
id: 'hello-world.blue'
Then the icon filename:
icon: 'icon.png'
Following comes the user-visible name of the package in any number of languages. For this example, we only provide English:
name: en: 'Hello Blue'
After this package level metadata, any number of applications can be added. In this simple example we define exactly one application and give it the same application id as the package. Since the application does not have an icon or name, it will inherit the package's icon and name.
applications: - id: 'hello-world.blue'
The code
field specifies the entry point of the application. For QML applications, this means the filename of its main QML file.
code: 'main.qml'
The runtime
field specifies the runtime used by the application. In this example, all applications are written in QML and hence we use the 'qml'
runtime. Another runtime is 'native'
for instance, used for compiled, executable, applications where the code
entry would point to its binary executable filename.
runtime: 'qml'
© 2024 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.