Rust and QML: a timely example

2017-09-10

It’s been a week since I announced Rust Qt Binding Generator.

Rust Qt Binding Generator (Logo by Alessandro Longo)

Since last week

A brief recap. The new project Rust Qt Binding Generator can create bindings between Rust code and Qt code. You can use Rust code to power your Qt application. Or in other words, you can use Qt as a cross-platform user interface for your Rust application.

You describe the interface between Rust and Qt in a simple JSON file. Then you compile the Rust code into a static library that you call from Qt. The user interface is still written in QML or C++. QML in particular is a wonderful language for writing user interfaces. And with these bindings, your Rust code will feel as a natural part of that user interface.

Today, I’ll walk through a very simple application. We’ll pretend that Qt code has no way to figure out the time, so we’ll implement code in Rust to ask the time.

But first an update on the happenings since the announcement of the bindings.

Live at KDE

The project is hosted at KDE. This is important to me. KDE is a community where software is created that gives the user control. It is a smoothly running organization that churns out releases of libraries and applications regularly.

Since this week the project is set up on the KDE infrastructure thanks to our admin team. That means bugzilla for bug reports, Phabricator for code browsing and patch review and Jenkins for continuous integration including code coverage.

The first translation commits and bot housekeeping commits have appeared already.

If you want to contribute, please create an account at the KDE community.

Time for QML

If you are new to QML, I can recommend the QML book. It walks you through many wonderful examples. In addition, Qt Creator comes with many more.

It is a tradition in KDE to use clocks as examples. I will follow this tradition and create a widget that shows the time.

We’ll start without any Rust at all. The initial version is only QML. It uses a simple SVG image as the background.

You can download this version and run it locally with qmlscene. qmlscene can run plain QML files. If you have QML plugins installed, these can be used too. You can make plugins that are implemented in Rust, but we’ll not go into that now.

The syntax of QML is declarative. The rotation of the Rust logo is given by the statement angle: time.second * 6. This is a binding. The value of angle updates automatically whenever time.second changes. The rotation of the logo changes every second because of this declarative binding.

Another example is anchors.fill: parent on the Image item. This means that the image takes up the same rectangular space as the parent item. If that item is resized, the image will scale along with it.

In this file, we added a temporary QtObject with properties hour, minute and second. The values in this object are updated every second by the Timer item. The JavaScript code between {} runs every second and updates the values in the QtObject. This object has id: time and the logo and hands are bound to this object.

The QtObject is a functional placeholder for the Rust code that we are going to write later.

templates/qt_quick.

You can get set up like so. You will need to have Qt, Rust and CMake installed.

First build rust_qt_binding_generator.

Antikythera mechanism by adding some Rust.

We want the Rust code to have a Time object that indicates the hour, the minute and the second. We write this interface into bindings.json.

this in main.qml. The third line imports our Rust object into the application. Our mockup QtObject and the Timer have been replaced with Time { id: time }.

This Time still has the properties hour, minute, and second. Whenever these change, the user interface is updated.

Post a comment