What makes a QML file (often called component) a well written good quality one?┬áLet’s take a look at example 1:

import QtQuick 2.9
MouseArea {
    anchors.right: parent.right
    anchors.bottom: parent.bottom
    id: button
    Rectangle {
        anchors.fill: parent
        color: "lightgray"
    }
    width: 100
    height: 20
    property string text: ""
    Text {
        anchors.centerIn: parent
        text: button.text
    }
    function foo() {
    }
}

And here almost the same as example 2:

import QtQuick 2.9
/**
  Simple push button like component
  No support for theming or icons are provided
  */
Item {
    id: root
    /// The text on the button
    property alias text: textItem.text
    /// The signal is emitted when the user clicked on the button
    signal clicked()
    implicitWidth: textItem.implicitWidth
    implicitHeight: textItem.implicitHeight
    width: implicitWidth
    height: implicitHeight
    Rectangle {
        id: backround
        anchors.fill: parent
        color: "lightgray"
    }
    Text {
        id: textItem
        anchors.centerIn: parent
    }
    MouseArea {
        id: clickArea
        anchors.fill: parent
        onClicked: {
            root.clicked();
        }
    }
    QtObject {
        id: internal
        function foo() {
        }
    }
}

I hope you agree that example 2 is a lot cleaner and easier to use. But let’s go through the list of differences:

  • The QML files should always have the same structure. Starting with the public API like properties, signals and functions. Then the derived properties that it sets and then the items it contains. The idea is that if someone want’s to use that component, he only needs to look at the top part. And when you navigate through the code it’s a lot easier.
  • The public API should be documented. Just like with any quality code.
  • The main Item the file consists of, has “root” as its id. It’s the id that is usually used the most in the file. And it’s easier if you always use the same id.
  • All items have an id set. I do this, as this gives a name to that item that describes what it is.
  • The id of an item is always in the first line.
  • The main item should not be derived from any other component that it not really is. It should rather be only a composition. Therefore the good one is a pure Item, and only contains the Rectangle, Text and MouseArea.
  • The implicit size is set and used as the default size. The implicit size is mostly used for dynamic layouts. The actual size can be overwritten when it’s used. But a sane default can be handy. In contrast, in the bad example the component already assumes on how it’s gonna be used – by setting anchors in this case.
  • Properties and functions that should not be used from outside should be hidden. I do this by moving them to an QtObject that I name internal (for me that’s similar to d-pointers in Qt C++). So the function is called by “internal.foo()” instead of “root.foo()” or just “foo()”. Another option is to start the name of “private” properties and functions with a double underscore (would be __foo() here).
  • For the text property an alias is used to to save duplication, memory and binding effort.

The example 2 is slightly more work. But as usual, quality code adds a bit extra effort. Which is not that much especially once one is used to it. So this short list covers already many aspects of a well written QML file that is easy to use. Following those ideas will help to generate reusable and more maintainable QML components.