Wie schreibt man sauberen QML-Code? Verbessern Sie die Qualität Ihres QML-Projekts

Qt QML-Entwicklung
2022-03-16
14 Minuten
Wie schreibt man sauberen QML-Code? Verbessern Sie die Qualität Ihres QML-Projekts

Deshalb müssen Sie lernen, sauberen QML-Code zu schreiben, um Ihr Qt-Entwicklungsprojekt leicht wartbar zu halten. Ergo, um Zeit und Geld zu sparen.

Zunächst, wenn Sie das Qt-Framework und dessen Funktionen nicht kennen, werfen Sie einen Blick auf unseren Blogbeitrag über Qt und wie man damit GUIs erstellt.

 

Was macht QML-Code sauber?

Beginnen wir mit der Frage: Was macht QML-Code sauber? Kann Code tatsächlich „schmutzig“ sein? Die Antwort lautet: Ja. Es gibt viele Dinge, die man in einem QML-Dokument falsch machen kann, ohne es zu merken.

 

QML-Code-Formatierung

Der Codestil ist die Art und Weise, wie der Code formatiert ist – also, wie er aussieht. Diese Definition ist meiner Meinung nach recht schlicht und einfach. Es stimmt zwar, dass die Formatierung die Ausführung der Anwendung in keiner Weise beeinflusst, aber sie hat einen erheblichen Einfluss auf die Lesbarkeit des Codes. Somit beeinflusst sie auch die Wartbarkeit der Anwendung und die Zeit, die zukünftige Entwickler benötigen, um Änderungen vorzunehmen.

Die Code-Formatierung umfasst die Einrückung für Eigenschaften, Funktionen und verschachtelte Objektdeklarationen. Sie betrifft den Einsatz von Leerzeichen und Zeilenumbrüchen, die Gruppierung von Code sowie die Organisation des QML-Objektbaums. Viele dieser Aspekte basieren auf persönlichen Vorlieben, und es lohnt sich nicht, über kleine Dinge wie die Position von öffnenden Klammern zu streiten.

Das Ziel ist es, eine konsistente Code-Formatierung im gesamten Projekt zu gewährleisten. Ich habe Softwareentwickler gesehen, die nicht einmal in ihrem eigenen Code konsistent bleiben konnten – und es wird noch schwieriger, wenn mehrere Personen an derselben Codebasis arbeiten. Deshalb sollten Sie versuchen, die Code-Formatierung zu automatisieren.

 

Tipp Nr. 1 für eine bessere QML-Code-Formatierung

QML-Code neigt dazu, viele Verschachtelungsebenen zu haben und sich schnell zu weit nach rechts auszudehnen. Daher wäre mein erster Tipp, die Einrückungsgröße auf 2 Leerzeichen zu reduzieren, um diesen Effekt zu begrenzen.

Um dies zu tun, öffnen Sie Qt Creator und navigieren Sie zu den Qt Quick-Einstellungen unter Optionen. Sie sollten einen Tab finden, der sich auf den Codestil bezieht. Den Standard-Codestil können Sie nicht bearbeiten, klicken Sie also auf die Kopieren-Schaltfläche, um Ihren eigenen Stil zu erstellen.

 

Nachdem Sie Ihrem Stil einen Namen gegeben haben, klicken Sie auf die Bearbeiten-Schaltfläche, um die Details des neu erstellten Stils anzupassen. Ich wünschte, es gäbe mehr Anpassungsmöglichkeiten, aber zumindest können hier die Einrückungseinstellungen geändert werden. Sie sollten sehen, dass sowohl die Tabulatorgröße als auch die Einrückungsgröße auf 4 eingestellt sind. Reduzieren Sie diese auf 2, und schon sind Sie fertig. Die Änderung sollte im Code-Editor sowie in Tools wie dem Reformat Datei-Tool sichtbar sein.

 

Tipp Nr. 2 für eine bessere QML-Code-Formatierung

Ein weiterer Tipp wäre, das Tool QML/JS Reformat File zu verwenden. Wie funktioniert das? Es nimmt Ihren Code und formatiert ihn neu, damit er übersichtlicher aussieht. Schauen wir uns die folgende Komponente an. Es ist nur zufälliger Code, um das Tool zu demonstrieren.

 

import QtQuick

Item
{
    id: root
    
    width:30;height:50;
    
    Text {
        id: textItem
        font.pixelSize: 48; wrapMode: Text.WordWrap
        lineHeight: 0.75
        Behavior on color { ColorAnimation { duration: 120; easing.type: Easing.OutElastic} }
        states: [State {
              name: "pressed"
                when: mouse.pressed
                PropertyChanges {
                  target:  textItem
                    color :Qt.lighter(root.color)
                }}
        ]
    }

    MouseArea {
        id: mouse
        anchors.fill: parent
        onClicked: {
            // ...
        }
    }

    function foo()
    {
        // ...
 }}

Das obige Beispiel ist definitiv nicht der schönste QML-Code, den Sie je gesehen haben. Es gibt mehrere Probleme, darunter uneinheitliche Einrückungen, falsche Klammerpositionen sowie fehlende oder überflüssige Leerzeichen. Um diese Probleme schnell und einfach zu beheben, navigieren Sie im oberen Menü von Qt Creator zur Option Tools und finden Sie unter der Gruppe QML/JS die Funktion Reformat File. Die Ausführung dieses Tools kann Ihnen viel Zeit sparen.

 

import QtQuick

Item {
  id: root

  width: 30
  height: 50

  Text {
    id: textItem
    font.pixelSize: 48
    wrapMode: Text.WordWrap
    lineHeight: 0.75
    Behavior on color {
      ColorAnimation {
        duration: 120
        easing.type: Easing.OutElastic
      }
    }
    states: [
      State {
        name: "pressed"
        when: mouse.pressed
        PropertyChanges {
          target: textItem
          color: Qt.lighter(root.color)
        }
      }
    ]
  }

  MouseArea {
    id: mouse
    anchors.fill: parent
    onClicked: {
      // ...
    }
  }

 function foo() {// ...
  }
}

Wenn Sie bereit sind, Qt Creator ein wenig Kontrolle über die Formatierung Ihres QML-Codes zu überlassen, sollten Sie versuchen, das Tool Reformat File so einzurichten, dass es automatisch beim Speichern einer Datei ausgeführt wird. Allerdings ist diese automatische Verarbeitung von QML-Code nicht immer perfekt.

 

Es gibt auch ein Tool namens qmlformat, das Sie neben der Installation des Qt-Frameworks finden können. Es handelt sich um ein Kommandozeilen-Tool, das im Wesentlichen dasselbe macht. Falls Sie also etwas suchen, das Sie über die Kommandozeile verwenden können, ist dieses Tool eine Option.

 

QML-Coding-Konventionen

Coding-Konventionen gehen über die reine Formatierung hinaus. Der QML-Code kann zwar schön formatiert und aus Sicht des Codestils in Ordnung sein, benötigt aber dennoch möglicherweise Nachbesserungen. Bei Scythe Studio sind wir recht streng mit unseren Coding-Konventionen, die leicht von den offiziellen QML-Coding-Konventionen abweichen, jedoch viele zusätzliche Konzepte einbringen, wie z. B. die Deklaration von Kinderobjekten in einer bestimmten Reihenfolge. Dennoch sind diese offiziellen Konventionen ein guter Ausgangspunkt, weshalb empfohlen wird, ihnen zu folgen.

Im Folgenden finden Sie einige der Konventionen, die wir bei Scythe Studio befolgen, um hochwertige Qt-Entwicklungsdienste anzubieten und sauberen QML-Code zu gewährleisten. Wir setzen die Einhaltung dieser Konventionen sogar bei Bewerbern durch, während sie an technischen Aufgaben im Rahmen der Bewerbungsphase arbeiten.

 

1. Benennen Sie das oberste Element in einer QML-Datei „root“

Um die Lesbarkeit und Nachverfolgbarkeit zu verbessern, wird empfohlen, die id eines obersten Elements in einer Datei auf root zu setzen. Auf diese Weise wissen Sie in jeder einzelnen QML-Datei, dass sich die Referenz auf root auf das oberste Element bezieht.

 

import QtQuick

Item {
  id: root
}

Genau das wurde im obigen Beispiel umgesetzt. Sie können es tatsächlich anders als root benennen, aber bei Scythe Studio machen wir es genau so, und viele andere verfahren ebenfalls auf diese Weise. Der Vorteil dabei ist, dass Sie selbst bei vielen verschachtelten Objektdeklarationen immer wissen, dass ein Kindobjekt, das root verwendet, sich auf das oberste Element im QML-Dokument bezieht.

2. Verwenden Sie ein einheitliches Format für String-Übersetzungen in jeder QML-Datei

Wenn ein String für den Benutzer sichtbar ist, umschließen Sie ihn immer mit der Funktion qsTr(). Außerdem sollten Sie anstelle von übersetzten Endstrings, die standardmäßig angezeigt werden, die Notation THIS_NOTATION verwenden. Zum Beispiel, anstatt text: qsTr(„This is displayed“) zu schreiben, verwenden Sie text: qsTr(„THIS_DISPLAYED“). Dank dieses Ansatzes können wir sofort im UI erkennen, wenn eine Übersetzung für einen String fehlt.

3. Haben Sie ein privates Objekt in Ihrem QML-Dokument

Kapselung und ein ordentlicher Geltungsbereich sollten auch beim Schreiben von QML-Code von Bedeutung sein. Genau wie in C++ möchten Sie nicht, dass alle Mitglieder Ihrer Klasse öffentlich sind, und das Gleiche sollte auch für den QML-Code gelten. Nicht alle Eigenschaften und Funktionen sollten von außen sichtbar sein.

Es gibt oft Bedarf an Hilfseigenschaften und -funktionen, die jedoch von außen keinen Mehrwert bieten oder sogar unerwarteten Schaden verursachen können. Daher wird empfohlen, sie in ein internes QtObject einzubetten. Die id-Eigenschaft eines solchen QML-Objekts setze ich oft einfach auf einen Unterstrich.

 

QtObject {
  id: _ // or id: internal
    
  readonly property real timeout: 1000
  property bool isExpanded: false

function addDestination() {
    // ...
  }
}

 

4. Reihenfolge der verschiedenen Attribute

Die offiziellen QML-Konventionen behandeln die Reihenfolge von Attributen und das vorgeschlagene Erscheinungsbild des QML-Objektbaums, aber wir definieren dies etwas anders und detaillierter. Für uns zahlt sich dieser Ansatz in großen Projekten aus. Hier ist unser Vorschlag, wie Kinderobjekte und Attribute in einer QML-Datei deklariert werden sollten:

 

import QtQuick
import QtQuick.Controls // Qt modules first
import com.scythestudio.ownmodule 1.0 // then own modules
import "./controls/" // then local directories

// A hypothetical custom button item.
Item {
  id: root

  /// The text to be placed on the button
  property string title: "title"                           // properties declaration
  /// The button's background color
  property alias color: button.color

  signal buttonClicked()                                   // signal declaration

  Button {                                                // child items
    id: button

    width: parent.width                                   // properties derived from Item
    height: parent.height

    icon.color: "black"                                   // Button's own properties

    onClicked: {
      root.buttonClicked()
 }
  }

  states: State {                                         // states
    name: "selected"
    PropertyChanges { target: button; icon.color: "red" }
  }

  transitions: Transition {                               // transitions
    from: ""
    to: "selected"
    ColorAnimation { target: button; duration: 200 }
  }

  PropertyAnimation {                                     // special items
    id: closeDelayAnimation
    // ...
  }

  Timer {                                                 // special items

  }

  Connections {                                           // special items
    target: someCppController

    function onProcessFailed() {
      // ...
    }
  }

  QtObject {                                               // private item
    id: _

    readonly property real timeout: 1000
    property bool isExpanded: false

    function addDestination() {
        // ...
    }
  }

  onWidthChanged: {                                       // slots

  }

  function close() {                                      // public functions
    isExpanded = false
    closeDelayAnimation.start()
  }
}

Aus dem obigen Code-Snippet können Sie viele Regeln über den QML-Objektbaum und die Attributsreihenfolge ableiten. Es sollte Ihnen Hinweise geben, wie Sie QML-Code schreiben und Kinderobjekte definieren können. Lassen Sie uns einige der Regeln hervorheben:

  • Die Reihenfolge jeder Import-Anweisung ist nicht zufällig. Import-Anweisungen für eingebaute Qt-Module sollten über den eigenen Modulen stehen;

  • Funktionsdefinitionen sollten bevorzugt am Ende der Datei stehen, um zunächst die QML-Objekte der Kinderkomponenten zu sehen und schnell zu verstehen, wie das Element visuell aufgebaut ist. Schließlich definiert QML-Code zuerst das Aussehen und dann den Ablauf der Anwendung;

  • States und Transitions neigen dazu, schnell umfangreich zu werden, weshalb sie unterhalb der Kinderobjekte platziert werden sollten, obwohl sie ebenfalls Eigenschaften sind;

  • Die öffentliche API der Komponente (Eigenschaften und Funktionen) sollte dokumentiert werden.

 

 Gute QML-Praktiken

In der Dokumentation des Qt-Frameworks finden Sie eine Liste der besten Praktiken für QML und Qt Quick. Ich finde all diese Tipps sehr nützlich, und einige davon sind grundlegend, um sauberen QML-Code zu schreiben. Wahrscheinlich die wichtigste Regel, die auf dieser Seite beschrieben wird, ist die Regel, die Benutzeroberfläche von der Logik zu trennen.

Wenn Sie mit QML programmieren, könnten Sie versucht sein, QML und JavaScript für viele Dinge zu verwenden, einschließlich Anwendungslogik und Netzwerkkommunikation.

 
QML code good practices

 

Vermeiden Sie zu viel Logik in der QML-Datei

Versuchen Sie, solche Dinge in C++ auszulagern, um eine klare Trennung zwischen dem in QML geschriebenen Frontend und, sagen wir, dem in C++ geschriebenen Backend zu schaffen. Dadurch wird die Architektur Ihrer Anwendung skalierbarer. Eine der Dinge, die fast immer in C++ geschrieben werden sollten, sind Datenmodelle. QML-Modelle können nur verwendet werden, wenn Ihre Liste statisch ist. Andernfalls werden Sie entweder viel Zeit verlieren, um fortgeschrittene Operationen mit QML-Modellen auszuführen, oder diese letztendlich in C++-Modelle umschreiben müssen.

In diesem Blogpost über Verbesserung der Leistung und Optimierung von QML-Apps finden Sie viele weitere Gründe, Logik in C++ zu implementieren. Es gibt dort zahlreiche Benchmarks, die diesen Punkt untermauern. Sehen wir es so: Sauberer QML-Code definiert die Benutzeroberfläche, nicht die kritischen Funktionen der Anwendung.

Bei Scythe Studio führen wir Online- und Offline-Workshops durch, die sich mit verschiedenen Aspekten der Qt-Softwareentwicklung befassen. Eines der Workshop-Themen ist „Fortgeschrittene Qt QML“. Sehen Sie sich unser Angebot zu Qt-Schulungen und C++-Workshops an, um mehr zu erfahren.

 

Pflegen Sie Ihre QML-Dateien mit qmllint

Eine weitere gute Praxis ist die Verwendung des qmllint tools, das Ihnen hilft, Probleme in Ihrem QML-Code leichter zu erkennen. Es ist ein äußerst nützliches Tool, das vor vielen Problemen warnt, darunter ungenutzte Importe und unqualifizierter Zugriff auf Eigenschaften. Seit Qt 6 ist es sogar hervorragend in die Qt Creator IDE integriert.

Sie können qmllint sogar so konfigurieren, dass es eine JSON-Ausgabe liefert. Nach der Verarbeitung des QML-Codes erhalten Sie dann alle Probleme und Fehler in einem Format, das Sie in GitHub, GitLab oder andere CI/CD-Tools integrieren können.

 

Strukturieren Sie Ihre QML-Objekte mit Qt-Modulen und CMake-Methoden

Auf dem Qt World Summit 2022 hielt ich einen Vortrag mit dem Titel CMake and Qt: qt_add_qml_module() in practice. Ich empfehle Ihnen, dieses Video auf YouTube anzusehen. Ziel des Vortrags war es, zu erklären, was Module im QML-Code sind und wie Sie sie verwenden können, um Ihre QML-Objekte sinnvoll zu strukturieren.

Einfach ausgedrückt sind Module eine Möglichkeit, Ihre QML-Dateien und JavaScript-Codes in Paketen zu organisieren, ähnlich wie C++-Namespaces. So können Sie Elemente wie UI-Steuerelemente oder grundlegende Hilfsobjekte (Constants, Theme usw.), die im gesamten Quellcode verwendet werden, in getrennten Modulen mit aussagekräftigen Namen ablegen.

Gründe für die Verwendung von QML-Modulen:

Ich werde nicht auf technische Details eingehen, da dies in der Präsentation ausführlich erklärt wurde. Die Vorteile der Verwendung von Modulen sind jedoch:

  • Möglichkeit, Funktionen und Elemente zu trennen;

  • Eine modularisierte Projektstruktur, die die Verwendung bestimmter Module in vielen Teilprojekten erleichtert;

  • Teilen von QML-Quellcodesammlungen in Form von Bibliotheken;

  • Saubere und wartbare Codebasis;

  • Möglichkeit, Versionierung einzuführen.

 

Warum ist es wichtig, sauberen QML-Code zu schreiben?

An diesem Punkt sollten Sie wissen, was sauberer Code bedeutet und was Sie tun können, um sicherzustellen, dass der von Ihnen geschriebene Code diesen Regeln entspricht. Lassen Sie uns also die Frage beantworten: Warum ist es so wichtig, sauberen QML-Code zu schreiben? Es ist einer der Faktoren, die Ihren Code zu hochwertigem Code machen.

 
Clean QML code benefits

 

Reduzierung des Aufwands während einer Überprüfung

Wenn Sie über ein Set an Konventionen und Regeln verfügen, die Sie einhalten, wird es einfacher, Fehler zu erkennen, was sofort Zeitersparnis bedeutet. Darüber hinaus schreiben Entwickler, die diese Richtlinien befolgen, gemäß den bewährten Praktiken, die in den Konzepten für sauberen Code enthalten sind. Das erfordert dann weniger Aufwand im Überprüfungsprozess. Ihre Senior-Entwickler müssen sich zudem nicht mit zahlreichen kleinen visuellen Syntaxproblemen beschäftigen.

 

Fokus auf wichtigere Aspekte

Während des Programmierens gibt es unzählige kleine Entscheidungen zu treffen. Wenn Sie denselben Code später erneut betrachten, wissen Sie oft nicht mehr, warum Sie ihn auf eine bestimmte Weise geschrieben haben. Wenn Sie jedoch die Regeln für sauberen QML-Code befolgen, delegieren Sie diese kleinen Entscheidungen an den Code. Das entlastet Ihre Denkressourcen.

 

Verbesserte Wartbarkeit des Projekts

Schließlich ist der wichtigste Grund, sauberen QML-Code zu schreiben, die Tatsache, dass er die Wartbarkeit des Projekts erheblich verbessert. Es heißt, dass Code einmal geschrieben, aber mehrfach gelesen wird. Daher sollten Sie sowohl auf die Lesbarkeit Ihres Codes als auch auf alle bewährten Praktiken achten. Das macht es Ihnen und anderen Entwicklern einfacher, in ein Projekt einzusteigen, einen bestimmten Teil zu verstehen und Änderungen vorzunehmen.

Das hängt von der Dauer des Projekts ab, an dem Sie gerade arbeiten, sowie von der Anzahl der Personen, die daran teilnehmen oder in Zukunft teilnehmen werden. Meiner Meinung nach ist es schwierig, bei der Sicherstellung einer hohen Codequalität zu übertreiben.

Selbst wenn Sie nur eine kleine Demo erstellen, deren Code öffentlich zugänglich sein wird, ist es sinnvoll, alle diese Regeln zu befolgen, um letztlich mit den Ergebnissen Ihrer Arbeit zufrieden zu sein. Nach einer Weile wird es zur Routine, und Entwickler hören auf, es als zusätzlichen Aufwand zu betrachten.

Wenn Sie ein langfristiges Projekt wie das Qt-Framework betreuen, gibt es viele Gründe, besonders streng auf die Codequalität zu achten. Meine Erfahrungen mit Beiträgen zum Modul Qt Charts in Qt 6.2 habe ich in einem Blogpost beschrieben. Es gibt viele Konventionen und Regeln zu beachten, was anfangs recht schwierig sein kann.

Zum Glück gibt es CI/CD-Mechanismen, die den Rezensenten Zeit sparen, indem sie beispielsweise nach Tippfehlern suchen. Anfangs war es eine Herausforderung, meinen Code an all diese Anforderungen anzupassen. Dennoch weiß ich, dass dies bei einem solchen Projekt unverzichtbar ist, und ich kann sagen, dass es letztlich sogar Spaß gemacht hat.

Ein grundlegendes CI/CD-Setup für Qt-QML-Projekte wurde im Blogpost Plattformübergreifende Qt CI/CD-Einrichtung – einfach gemacht erklärt.

 

Wichtige Erkenntnisse und allgemeine Regeln

Lassen Sie uns den Blogpost zusammenfassen, um die wichtigsten Regeln für das Schreiben von sauberem QML-Code noch einmal in Erinnerung zu rufen. Viele dieser Regeln sollten unabhängig von der verwendeten Technologie auf Ihr Projekt und Ihren Quellcode angewendet werden.

  • Eine saubere QML-Codebasis zu pflegen, ist ein wichtiger Aspekt eines gesunden Qt-Projekts.

  • KISS – Keep it short and simple. Nicht für Sie, sondern für den Leser. Wählen Sie immer die einfachere Implementierungsoption gegenüber der komplizierteren.

  • Dokumentieren Sie öffentliche Schnittstellen (APIs) der erstellten Elemente.

  • Fügen Sie keine Kommentare hinzu, die beschreiben, wie etwas erreicht wird. Wenn der Leser dies aus Ihrem Code nicht ableiten kann, muss der Code refaktoriert werden. Kommentieren Sie hingegen nicht offensichtliche Lösungen, die überraschend wirken könnten.

  • Erfinden Sie das Rad nicht neu.

  • Passen Sie den Code an die bestehende Codebasis an. Wenn Sie Verbesserungsideen haben, besprechen Sie diese zuerst mit anderen Entwicklern.

  • Folgen Sie den Codierkonventionen und bewährten QML-Praktiken.

 

Scythe-Studio - Chief Executive Officer

Łukasz Kosiński Chief Executive Officer

Brauchen Sie Qt QML-Entwicklungsdienste?

service partner

Kommen wir zur Sache: Es ist eine Herausforderung, Top-Qt-QML-Entwickler zu finden. Helfen Sie sich selbst und starten Sie die Zusammenarbeit mit Scythe Studio – echten Experten im Qt C++ Framework.

Entdecken Sie unsere Fähigkeiten!

Neueste Artikel

[ 156 ]