
Visualisierung von Gesundheitsdaten
Da die Gesundheitsbranche immer mehr Daten generiert, liegt die Herausforderung nicht mehr nur in der Datensammlung, sondern in der Interpretation. […]
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.
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.
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.
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.
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.
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.
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.
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.
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() { // ... } }
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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!Da die Gesundheitsbranche immer mehr Daten generiert, liegt die Herausforderung nicht mehr nur in der Datensammlung, sondern in der Interpretation. […]
Produkte aus der STM32-Familie sind seit langer Zeit ein beliebtes Ziel für eingebettete Qt-Anwendungen. Eine der beliebtesten Optionen war über […]
Ich begrüße Sie zu einem weiteren Blogbeitrag. Der letzte Beitrag behandelte eine Form der Kommunikation zwischen Geräten mit Qt Bluetooth […]