Creating our QML GUI

As noted in the QObjects in Rust chapter, we always want to use "the right tool for the right job". For a small modern GUI in Qt, that definitely means using QML. It's powerful, flexible, declarative, and allows us to iterate very quickly.

So let's add a main.qml file in a qml folder:

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12

// This must match the uri and version
// specified in the qml_module in the build.rs script.
import com.kdab.cxx_qt.demo 1.0

Window {
    height: 480
    title: qsTr("Hello World")
    visible: true
    width: 640

    MyObject {
        id: myObject
        number: 1
        string: qsTr("My String with my number: %1").arg(myObject.number)
    }

    Column {
        anchors.fill: parent
        anchors.margins: 10
        spacing: 10

        Label {
            text: qsTr("Number: %1").arg(myObject.number)
        }

        Label {
            text: qsTr("String: %1").arg(myObject.string)
        }

        Button {
            text: qsTr("Increment Number")

            onClicked: myObject.incrementNumber()
        }

        Button {
            text: qsTr("Say Hi!")

            onClicked: myObject.sayHi(myObject.string, myObject.number)
        }
    }
}

If you're not familiar with QML, take a look at the Qt QML intro. We of course also recommend our QML Intro Training.

This code will create a pretty simple GUI that consists of two Labels and two Buttons. The important part here is the use of the MyObject type. As you can see, the class we defined earlier is now usable in QML.

As it is just another QObject subclass, it can be used in Qt's property binding system, as is done with the myObject.string, which is bound to myObject.number.

The labels then simply display the data defined in the MyObject class. We can use the two buttons to interact with the MyObject instance. As you can see here, CXX-Qt has converted the snake_case of the function names to camelCase - incrementNumber and sayHi. This way the MyObject doesn't seem at all out of place in QML.

It is again important to emphasize here that MyObject is just another QObject subclass and can be used just like any other QObject subclass. The only difference being that any invokable functions are defined in Rust, instead of C++. For QML, this doesn't make a difference though.

Now that we have some application code, let's get this project building and running