Bewährte Praktiken für QML und Qt Quick

Trotz all der Vorteile, die QML und Qt Quick bieten, können sie in bestimmten Situationen eine Herausforderung darstellen. In den folgenden Abschnitten werden einige bewährte Verfahren erläutert, mit denen Sie bei der Entwicklung von Anwendungen bessere Ergebnisse erzielen können.

Benutzerdefinierte UI-Steuerelemente

Eine flüssige und moderne Benutzeroberfläche ist der Schlüssel zum Erfolg jeder Anwendung in der heutigen Welt, und genau hier macht QML für einen Designer oder Entwickler so viel Sinn. Qt bietet die grundlegendsten UI-Steuerelemente, die zur Erstellung einer flüssigen und modern aussehenden Benutzeroberfläche erforderlich sind. Es wird empfohlen, diese Liste von UI-Steuerelementen durchzusehen, bevor Sie Ihr eigenes benutzerdefiniertes UI-Steuerelement erstellen.

Neben diesen grundlegenden UI-Steuerelementen, die von Qt Quick selbst angeboten werden, ist auch ein umfangreicher Satz von UI-Steuerelementen unter Qt Quick Controls verfügbar. Sie decken die gängigsten Anwendungsfälle ohne Änderungen ab und bieten mit ihren Anpassungsoptionen viel mehr Möglichkeiten. Insbesondere bietet Qt Quick Controls Styling-Optionen, die sich an den neuesten UI-Design-Trends orientieren. Wenn diese UI-Steuerelemente den Anforderungen Ihrer Anwendung nicht genügen, ist es empfehlenswert, ein benutzerdefiniertes Steuerelement zu erstellen.

Sie können die Steuerelemente beim Entwurf von Benutzeroberflächen in Qt Design Studio verwenden. Darüber hinaus bietet es zeitleistenbasierte Animationen, visuelle Effekte, Layouts und eine Live-Vorschau für das Prototyping von Anwendungen.

Kodierungskonventionen

Siehe QML-Codierungskonventionen.

Anwendungsressourcen bündeln

Die meisten Anwendungen sind auf Ressourcen wie Bilder und Symbole angewiesen, um dem Benutzer ein ansprechendes Erlebnis zu bieten. Es kann oft eine Herausforderung sein, diese Ressourcen unabhängig vom Zielbetriebssystem für die Anwendung verfügbar zu machen. Die meisten gängigen Betriebssysteme verwenden strengere Sicherheitsrichtlinien, die den Zugriff auf das Dateisystem einschränken und das Laden dieser Ressourcen erschweren. Als Alternative bietet Qt ein eigenes Ressourcensystem, das in das Anwendungsbinary integriert ist und den Zugriff auf die Ressourcen der Anwendung unabhängig vom Zielbetriebssystem ermöglicht.

Betrachten Sie zum Beispiel die folgende Projektverzeichnisstruktur:

MyModule
├── images
│   ├── image1.png
│   └── image2.png
├── CMakeLists.txt
└── main.qml

Sie können diese Struktur als CMake-QML-Modul folgendermaßen darstellen:

qt_add_qml_module(my_module
   URI MyModule
   VERSION 1.0
   QML_FILES
       main.qml
   RESOURCES
       images/image1.png
       images/image2.png
   # ...
)

Alle QML-Dateien, die unter QML_FILES aufgeführt sind, werden automatisch im Voraus kompiliert.

Sie sollten die QML-Dateien im gleichen Verzeichnis wie die CMakeLists.txt mit dem qt_add_qml_module halten. Ansonsten unterscheiden sich ihre impliziten Importe von den QML-Modulen, zu denen sie gehören. Dies ist eine häufige Quelle von Fehlern.

UI von der Geschäftslogik trennen

Eines der Hauptziele, das die meisten Anwendungsentwickler erreichen wollen, ist die Erstellung einer wartbaren Anwendung. Eine der Möglichkeiten, dieses Ziel zu erreichen, ist die Trennung der Benutzeroberfläche von der Geschäftslogik. Im Folgenden werden einige Gründe genannt, warum die Benutzeroberfläche einer Anwendung in QML geschrieben werden sollte:

  • Deklarative Sprachen eignen sich hervorragend für die Definition von Benutzeroberflächen.
  • QML-Code ist einfacher zu schreiben, da er weniger ausführlich ist als C++ und nicht stark typisiert ist. Dies führt auch dazu, dass man in dieser Sprache hervorragend Prototypen erstellen kann, eine Eigenschaft, die z. B. bei der Zusammenarbeit mit Designern wichtig ist.
  • JavaScript kann in QML leicht verwendet werden, um auf Ereignisse zu reagieren.

Da C++ eine stark typisierte Sprache ist, eignet sie sich am besten für die Geschäftslogik einer Anwendung. Typischerweise führt dieser Code Aufgaben wie komplexe Berechnungen oder Datenverarbeitung aus, die in C++ schneller sind als in QML.

Qt bietet verschiedene Ansätze zur Integration von QML- und C++-Code in einer Anwendung. Ein typischer Anwendungsfall ist die Anzeige einer Liste von Daten in einer Benutzeroberfläche. Wenn der Datensatz statisch, einfach und/oder klein ist, kann ein in QML geschriebenes Modell ausreichend sein.

Das folgende Snippet zeigt Beispiele für in QML geschriebene Modelle:

model: [ "Item 1", "Item 2", "Item 3" ]

model: 10

Verwenden Sie C++ für dynamische Datensätze, die groß sind oder häufig geändert werden.

Daten von C++ nach QML freigeben

Das Refactoring von QML ist viel einfacher als das Refactoring von C++. Um die Wartung schmerzfrei zu gestalten, sollten wir uns bemühen, C++-Typen so weit wie möglich von QML fernzuhalten. Dies kann erreicht werden, indem Referenzen auf C++-Typen in QML "geschoben" werden.

Dies kann durch die Verwendung von erforderlichen Eigenschaften und deren Einstellung über QQmlApplicationEngine::setInitialProperties geschehen. Es ist auch möglich, eine oder mehrere singletons zu erstellen, die alle Daten zurückgeben, die die C++-Seite QML zur Verfügung stellen möchte.

Bei diesem Ansatz bleibt C++ unverändert, falls die QML in der Zukunft umgestaltet werden muss.

Eine Kurzanleitung für die Wahl des richtigen Ansatzes zur Bereitstellung von C++-Typen für QML finden Sie unter Wahl der richtigen Integrationsmethode zwischen C++ und QML.

Verwendung von Qt Design Studio

Qt Design Studio verwendet UI-Dateien mit der Dateinamenerweiterung .ui.qml, um die visuellen Teile der Benutzeroberfläche von der UI-Logik zu trennen, die Sie in .qml-Dateien implementieren. Sie sollten UI-Dateien nur in der Ansicht 2D in Qt Design Studio bearbeiten. Wenn Sie ein anderes Werkzeug verwenden, um Code hinzuzufügen, der von Qt Design Studio nicht unterstützt wird, werden Fehlermeldungen angezeigt. Beheben Sie die Fehler, um die visuelle Bearbeitung der UI-Dateien wieder zu ermöglichen. Normalerweise sollten Sie den nicht unterstützten Code in eine .qml-Datei verschieben.

Verwendung von Qt Quick Ansichten

Status in Modellen speichern

Siehe Avoid Storing State in Delegates.

Qt Quick Layouts verwenden

Qt bietet Qt Quick Layouts, um Qt Quick Elemente visuell in einem Layout anzuordnen. Im Gegensatz zu ihrer Alternative, den Item Positioners, können die Qt Quick Layouts auch die Größe ihrer Kinder bei der Größenänderung des Fensters ändern. Obwohl Qt Quick Layouts für die meisten Anwendungsfälle die gewünschte Wahl sind, müssen bei ihrer Verwendung die folgenden Dos und Don'ts beachtet werden:

Dos

  • Verwenden Sie anchors oder die Eigenschaften width und height, um die Größe des Layouts im Vergleich zu seinem übergeordneten Element, das kein Layout ist, festzulegen.
  • Verwenden Sie die Eigenschaft Layout attached, um die Größen- und Ausrichtungsattribute der unmittelbaren Kinder des Layouts festzulegen.

Tipps und Tricks

  • Definieren Sie keine bevorzugten Größen für Elemente, die implicitWidth und implicitHeight bieten, es sei denn, ihre impliziten Größen sind nicht zufriedenstellend.
  • Verwenden Sie keine Anker für ein Element, das ein unmittelbares Kind eines Layouts ist. Verwenden Sie stattdessen Layout.preferredWidth und Layout.preferredHeight:
    RowLayout {
        id: layout
        anchors.fill: parent
        spacing: 6
        Rectangle {
            color: 'orange'
            Layout.fillWidth: true
            Layout.minimumWidth: 50
            Layout.preferredWidth: 100
            Layout.maximumWidth: 300
            Layout.minimumHeight: 150
            Text {
                anchors.centerIn: parent
                text: parent.width + 'x' + parent.height
            }
        }
        Rectangle {
            color: 'plum'
            Layout.fillWidth: true
            Layout.minimumWidth: 100
            Layout.preferredWidth: 200
            Layout.preferredHeight: 100
            Text {
                anchors.centerIn: parent
                text: parent.width + 'x' + parent.height
            }
        }
    }

Hinweis: Layouts und Anker sind beides Objekttypen, die mehr Speicher und Zeit für die Instanziierung benötigen. Vermeiden Sie die Verwendung von Layouts (insbesondere in Listen- und Tabellendelegaten und Stilen für Steuerelemente), wenn einfache Bindungen an x-, y-, Breiten- und Höheneigenschaften ausreichend sind.

Typsicherheit

Bei der Deklaration von Eigenschaften in QML ist es einfach und bequem, den Typ "var" zu verwenden:

property var name
property var size
property var optionsMenu

Dieser Ansatz hat jedoch mehrere Nachteile:

  • Wenn ein Wert mit dem falschen Typ zugewiesen wird, verweist die Fehlermeldung auf den Ort der Eigenschaftsdeklaration und nicht auf den Ort, an dem die Eigenschaft zugewiesen wurde. Dies verlangsamt den Entwicklungsprozess, da es schwieriger ist, Fehler aufzuspüren.
  • Eine statische Analyse zum Aufspüren von Fehlern wie den oben genannten ist nicht möglich.
  • Der tatsächlich zugrunde liegende Typ der Eigenschaft ist für den Leser nicht immer sofort ersichtlich.

Verwenden Sie stattdessen nach Möglichkeit immer den tatsächlichen Typ:

property string name
property int size
property MyMenu optionsMenu

Leistung

Informationen zur Leistung in QML und Qt Quick finden Sie unter QML Performance Considerations And Suggestions.

Bevorzugen Sie deklarative Bindungen gegenüber imperativen Zuweisungen

In QML ist es möglich, imperativen JavaScript-Code zu verwenden, um Aufgaben wie das Reagieren auf Eingabeereignisse, das Senden von Daten über ein Netzwerk usw. auszuführen. Imperativer Code hat einen wichtigen Platz in QML, aber es ist auch wichtig zu wissen, wann man ihn nicht verwenden sollte.

Betrachten Sie zum Beispiel die folgende imperative Zuweisung:

Rectangle {
    Component.onCompleted: color = "red"
}

Dies hat die folgenden Nachteile:

  • Sie ist langsam. Die Farbeigenschaft wird zuerst mit einem standardmäßig konstruierten Wert ausgewertet, und dann später noch einmal mit "rot".
  • Es verzögert Fehler, die zur Erstellungszeit gefunden werden könnten, auf die Laufzeit, was den Entwicklungsprozess verlangsamt.
  • Es überschreibt alle deklarativen Bindungen, die bereits vorhanden waren. In den meisten Fällen ist dies beabsichtigt, aber manchmal kann es auch ungewollt sein. Weitere Informationen finden Sie unter Debuggen des Überschreibens von Bindungen.
  • Es stört das Tooling; Qt Quick Designer zum Beispiel unterstützt kein JavaScript.

Der Code kann umgeschrieben werden, um stattdessen eine deklarative Bindung zu erstellen:

Rectangle {
    color: "red"
}

Speichern Sie keinen Zustand in Delegaten

Speichern Sie keinen Zustand in einem Delegaten. Das Problem dabei ist, dass der Delegat mehrfach erstellt und zerstört wird, so dass der gespeicherte Zustand verloren geht.

// Wrong approach:
ListView {
    // ...

    delegate: Button {
        // ...
        property bool someStateProperty
        onClicked: someStateProperty = true
    }
}

Speichern Sie den Zustand stattdessen außerhalb des Delegaten. Zum Beispiel in einem Modell. Wenn der Delegat zerstört wird, geht der gespeicherte Zustand nicht verloren.

// Right approach:
ListView {
    // ...

    delegate: Button {
        // ...
        onClicked: model.someStateProperty = true
    }
}

Machen Sie benutzerseitige Zeichenketten übersetzbar

Es wird empfohlen, benutzerseitige Zeichenketten von Anfang an übersetzbar zu machen. Siehe Quellcode für die Übersetzung schreiben.

ToolButton {
    id: selectionToolButton
    // ...
    icon.source: "qrc:/images/selection.png"

    Tooltip.Text: qsTr("Select pixels within an area and move them")

    onClicked: canvas.tool = ImageCanvas.SelectionTool
}

Keine Anpassung der nativen Stile

Native Stile (Windows- und macOS-Stile) unterstützen keine Anpassungen. Stellen Sie sicher, dass Sie einen nativen Stil nicht anpassen.

// Wrong approach:
import QtQuick.Controls.Windows

// Don't customize a native style
Button {
    background: Rectangle { /*...*/ }
}

Es wird stattdessen empfohlen, ein angepasstes Steuerelement immer auf einem einzigen Stil zu basieren, der auf allen Plattformen verfügbar ist, z. B. Basic Style, Fusion Style, Imagine Style, Material Style, Universal Style. Auf diese Weise ist gewährleistet, dass das Steuerelement immer gleich aussieht, unabhängig davon, mit welchem Stil die Anwendung ausgeführt wird. Wie Sie einen anderen Stil verwenden können, erfahren Sie unter Verwendung von Stilen in Qt Quick Controls. Alternativ können Sie auch einen eigenen Stil erstellen.

// Right approach:
import QtQuick.Controls.Basic

// You can customize a commonly available style
Button {
    background: Rectangle { /*...*/ }
}

Werkzeuge und Dienstprogramme

Informationen über nützliche Tools und Dienstprogramme, die die Arbeit mit QML und Qt Quick erleichtern, finden Sie unter Qt Quick Tools und Dienstprogramme.

Szenendiagramm

Informationen über den Szenegraph von Qt Quick finden Sie unter Qt Quick Szenegraph.

Skalierbare Benutzerschnittstellen

Mit der Verbesserung der Bildschirmauflösungen wird eine skalierbare Benutzeroberfläche für Anwendungen immer wichtiger. Einer der Ansätze, um dies zu erreichen, besteht darin, mehrere Kopien der Benutzeroberfläche für verschiedene Bildschirmauflösungen zu pflegen und je nach verfügbarer Auflösung die passende zu laden. Obwohl dies recht gut funktioniert, erhöht es den Wartungsaufwand.

Qt bietet eine bessere Lösung für dieses Problem und empfiehlt den Anwendungsentwicklern, diese Tipps zu befolgen:

  • Verwenden Sie Anker oder das Modul Qt Quick Layouts, um die visuellen Elemente anzuordnen.
  • Geben Sie nicht explizit Breite und Höhe für ein visuelles Element an.
  • Stellen Sie UI-Ressourcen wie Bilder und Symbole für jede von Ihrer Anwendung unterstützte Bildschirmauflösung bereit. Das Beispiel der Galerie Qt Quick Controls demonstriert dies gut, indem qt-logo.png für die Auflösungen @2x, @3x und @4x bereitgestellt wird, so dass die Anwendung auch für hochauflösende Displays geeignet ist. Qt wählt automatisch das passende Bild aus, das für die gegebene Anzeige geeignet ist, vorausgesetzt die Funktion zur Skalierung auf hohe DPI-Werte ist explizit aktiviert.
  • Verwenden Sie SVG-Bilder für kleine Icons. Während größere SVGs langsam gerendert werden können, funktionieren kleine SVGs gut. Bei Vektorbildern müssen Sie nicht mehrere Versionen eines Bildes bereitstellen, wie es bei Bitmap-Bildern erforderlich ist.
  • Verwenden Sie auf Schriftarten basierende Icons, wie Font Awesome. Diese lassen sich auf jede Bildschirmauflösung skalieren und können auch eingefärbt werden. Das Beispiel des Qt Quick Controls Texteditors demonstriert dies gut.

Auf diese Weise sollte die Benutzeroberfläche Ihrer Anwendung je nach der angebotenen Bildschirmauflösung skaliert werden.

© 2025 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.