Book Review: Cross-Platform Development with Qt 6 and Modern C++

I recently received a review copy of the Cross-Platform Development with Qt 6 and Modern C++ by Nibedit Dey available from Packt. I find it interesting to read books on Qt in the midst of a major version shift, as many of the underpinnings of Qt are revisited and updated by the development teams.

In his book, Nibedit balances between the newer technologies used, e.g. CMake, function reference based signals and slots, etc while referring back to Qt 5 (and even Qt 4) practices such as QMake, the SIGNAL and SLOT macros, and more. This gives a good context to the reader, which is good for the reader, as older practices still are used in older Qt-based codebases.

The book is divided into blocks with increasing depth and complexity. This makes it a good read for the beginner, as well as the more experienced used of Qt. Either you start from the beginning and get introduced to both widgets and QML, or you can dive straight into the more advanced topics such as the model-view concepts.

What I particularly like about the book is the focus on the cross-platform capabilities of Qt. This is how Qt was started, and something that is often lost these days. Qt is more than a UI toolkit and the real strength is the ability to use a single code base to build native applications for the major desktop (and some not so major) as well as the major mobile platforms. This is a reoccuring theme throughout the book where it starts by installing the Qt development environment on all major platforms, discusses how to setup Qt for mobile development, as well as for how to deploy Qt applications in all these scenarios.

There are other highlights too such as the chapter on testing, discussions on profiling and optimizations, and other topics not commonly found in this type of book.

What could be said to be missing is any content on embedded device development, 3D tooling and classes, the design focused tooling, and more. But Qt is such a broad topic these days that it would be impossible to cover it all in a single book.

All in all, this is a recommended read!

Intense weeks

End of October turns out to be one of the highs when it comes to workload this year. Everything happens at once – there are two public events that I’d like to tell you about.

The first one is running lights. This is an annual running competition organized by AIF Friidrott, the sports club my kids are active in. This year, this means organized by me and postponed due to COVID-19, but the virtual races started this weekend and the arena race will take place on the 24th.

If anyone of you are in the Alingsås area and enjoy I highly recommend you to join. The weather looks nice, and we will light up the arena with live fire, so it will be a great evening.

The second one is the foss-north 2020 take II event. This spring, we decided to try to organize a physical foss-north event this fall, as obviously the pandemic must be over by November. This seems to not be the case. :-)

Instead we are running a single day event on November 1 with six handpicked speakers. The event is virtual and free for all.

I would like to tell you about the speakers one by one, because I’m very excited about each and everyone of them.

Andrew 'bunnie' Huang

In the morning we welcome Bunnie Huang who will talk about the precursor project. Precursor is an open hardware platform for secure, mobile communications and computations. The focus is on security aiming to create a trustable platform.

Simon Ser

Next up is Simon Ser. He will talk about how to get pixels onto the screen in a modern Linux stack. This means a deep dive in the Kernel Mode Setting (KMS) interface. How it exposes hardware blocks and how to use it to get images shown on the screen.

Ramón Soto Mathiesen

The morning session then ends with Ramón Soto Mathiesen taking us into the land of Domain Driven Design (DDD) using Algebraic Data Types (ADT). Ramón has a background in functional programming languages and brings this knowledge into the world of multi-paradigm languages such as C#, Rust, and Swift.

Carol Chen

The afternoon session starts with Carol Chen from Red Hat Ansible. She works as a community manager for Ansible. She will be talking about how they move have moved from collections to contributions to conferences.

Lars Brinkhoff

We then continue with Lars Brinkhoff who will talk about the Incompatible Timesharing System (ITS). Lars works with restoring ITS and recreating the history from these early days of computing. ITS is of particular interest at foss-north at is the platform where tools such as Lisp, Logo, Scheme, Emacs and Zork where developed. This is where the foundations for the free software movement where born – quite literally.

Tor-logo by Stanchenko on DeviantArt

The day then ends with Alexander and Georg who will talk about Tor, the anonymity network. They will discuss why diversity is essential for reaching security and anonymity.

So, the next days will be crazy hectic, but it is all for something good. First a cosy evening of running on an arena lit by live fire, and then a day of talks about various FOSS projects.

I hope to see you there!

Felgo in the QML Book

Over the past year I’ve been bumping into the Felgo crew at various Qt events. They take Qt to the next level. It all started as a game development framework for Qt, but has turned into a powerful app development framework taking a lot of the rough corners of Qt, and extending the tooling with a powerful live reloader at the same time.

https://qmlbook.github.io/_images/felgo-logo.png

To showcase how the Felgo SDK fits into the bigger picture, and how much it actually helps creating apps, we agreed to extend the QML Book with a Felgo chapter. The chapter is built around a messaging app and showcases the whole UI creation from initial skeleton to working app.

https://qmlbook.github.io/_images/messaging-stage-2.png

We also cover a bunch of other things such as how to get started, the QML Live reloader, as well as some more advanced topics such as native dialogs, simplified networking and the JsonListModel.

Big thanks goes out to Felgo for supporting this work and helping to make QML Book better.

Akademy 2020

I had the pleasure of speaking at Akademy 2020 this weekend. This year Akademy is virtual, but I still got the feeling of a very interactive event. Interesting questions, greenroom for the speakers, and generally a nice experience. Big thank you to the organizers!

The video below should start roughly when I go on stage.

For the interested listener, you can find the slides here: https://e8johan.se/presentations/2020-09%20akademy%20v1.1.pdf.

gbgcpp – Ribbons using Qt

I’ve been involved in the gbgcpp group, a part of the larger Sweden C++ community, for a couple of years. It is fun to see that there is a lot of C++ developers out there, once you start looking for them.

In the next meetup, this Wednesday, there will be both C++ and Qt. The topic is to implement Ribbons in Qt, based on a seminar by Dag Brück. If you happen to be in the vicinity of Gothenburg, I recommend you to go there!

I’d also like reach out and thank Sylog for hosting the event!

Free software and the wish to be good

The free software movement has recently been going through a lot. From the introduction of Commons Clause, to the resignation of Stallman. It seems like the mood in the air is that now is the time for a redefinition of what free and open source software actually is.

My view on this is that free software, and open source, is about software. For instance, I agree to Roman Gilg’s great post about activism. What we share within the FOSS movement is our passion for software licensing. For other political issues, we do not all agree. It is important to recognize this, and that by implying political standpoints, we limit the size of the communities.

To me, we in the FOSS movement need to define tackle two issues: what is distribution (to address the Common Clause issues), and can we be neutral to what the software is used for (to address the activism issues).

When it comes to distribution, the open source definition explicitly says “No Discrimination Against Persons or Groups” and “No Discrimination Against Fields of Endeavor“. I think we all can agree that software is used for both good and evil. However, what is good and what is evil depends on your viewpoint. I believe that the license should be free of this type of politics, as opening the discussion will be like opening a Pandora’s box.

If we, as a community, want to define good and and bad, and restrict usage accordingly, I would argue that we should make sure to use an established, and accepted standard such as The Universal Declaration of Human Rights. This would avoid creating an impenetrable forest of various uses that each author feels strongly about and prohibits. The latter would make it very difficult to ensure compliance.

When it comes to compliance, including a definition of good and restricting usage accordingly has an interesting effect. Common day objects such as cars, can be used for both good and evil. Is it allowed to use FOSS licensed software in a car, if that car could be used in activities breaking the human rights?

Another problem with incorporating human rights into the license, is that those who ignore the human rights probably don’t care about software licenses either.

The second point is the definition of distribution. Here I’m approaching the discussion from a GPL standpoint. The GPL licenses are triggered when software is distributed. By taking the distribution concept further, e.g. including access over a network, the license can be further extended.

Here, the balancing act is going far enough, but not too far, and to provide a range of licenses that make it easy for the authors to control how the software can be used.

The problem that I see with going too far, is that entire fields of endeavor might be excluded by extending the license to far. One example of this is the anti-Tivioization clauses in (L)GPLv3. We all know what purpose they serve. The side effect is that they exclude entire fields where the OEMs feel that, for liability or compliance reasons, they need to introduce Tivioization.

I see this in the automotive sector, but would assume that it exists in medtech and other industries where the final product needs to fulfill safety requirements.

For me, I think that the license should prevent Tivioization from an end-user standpoint. It should be possible to change and deploy the software. I believe it should be explicitly allowed to detect the non-OEM software and, for instance, void warranties and warn the end-user, but not prevent usage of the product (this in itself is interesting – can other physical devices refuse to talk to the device, e.g. a cloud backend, or other ECUs in the same car? – it will be tricky to define the boundaries here). This opens the door for FUD warnings, but it also extends the reach of FOSS.

Both these topics form a complex discussion that needs to be given time. The current open source definition serves us well, and the current licenses are familiar. Introducing more licenses, or even challenging the definition of open source, will introduce complexities and side effects, so we need to tread carefully.

foss-north 2019: Community Day


I don’t dare to count the days until foss-north 2019, but it is very soon. One of the changes to this year is that we expand the conference with an additional community day.

The idea with the community day here is that we arrange for conference rooms all across town and invite open source projects to use them for workshops, install fests, hackathons, dev sprints or whatever else they see fit. It is basically a day of mini-conferences spread out across town.

The community day is on April 7, the day before the conference days, and is free of charge.

This part of the arrangements has actually been one of the most interesting ones, as it involves a lot of coordination. I’d like to start by thanking all our room hosts. Without them, the day would not be possible!

The other half of the puzzle is our projects. I am very happy to see such a large group of projects willing to try this out for the first time, and I hope for lots and lots of visitors so that they will want to come back in the future as well.

The location of each project, as well as the contents of each room can be found on the community day page. Even though the day is free of charge, some of the rooms want you to pre-register as the seats might be limited, or they want to know if they expect five or fifty visitors. I would also love for you to register at our community day meetup, just to give me an indication of the number of participants.

Also – don’t forget to get your tickets for the conference days – and combine this with a training. We’re already past the visitor count of the 2018 event, so we will most likely be sold out this year!

Working on QML Book

Do you remember QML Book? It started as a project between me and Jürgen Bocklage-Ryannel where we tried to fix the problem that there is no QML book out there.

Back in the Qt 5.2 days, we spent wrote about a year. Unfortunately, the project has mainly been sitting idle since then. I’ve poked at issues every now and then, and Jürgen has done various fixes as well.

Thanks to The Qt Company, this is changing. This autumn, it sponsors me to work on the project. The current plan is to add a chapter to Qt Quick Controls 2, and to update the entire contents to Qt 5.12 and Qt Creator 4.8. By doing so, many of the remaining bug reports will be resolved.

Other things in the backlog are getting the CI system back into shape and having a native speaker edit the language. All in all, this will result in an up-to-date book on QML. If you want to help out, just reach out to me or send me your pull requests. All help is welcome!

QML Weather

I recently took some time to develop a photo frame style home automation control panel. The idea is to control some common tasks of my home assistant setup from a panel instead of having to rely on the phone. To hide the panel, it currently act as a photo frame until touched.

The build is based on a Raspberry Pi 2 with the official touch screen attached and a USB wifi dongle. Nothing fancy, but still good enough.

One of the features that I wanted was a weather forecast, so I decided to use Yr’s xml weather as a base for this. The result is the YrWeatherModel QML item.

The weather forecast overlay.

The presentation side of things is the fairly straight forward piece of QML shown below, resulting in the overlay shown above.

Row {
    anchors.bottom: dateText.bottom
    anchors.right: parent.right
    anchors.rightMargin: 40

    spacing: 20
    Repeater {
        delegate: Column {
            spacing: 2
            Text {
                anchors.horizontalCenter: parent.horizontalCenter
                color: "white"
                font.pixelSize: 16
                font.bold: true
                text: {
                    switch (period) {
                    case 0:
                        "00 - 06"
                        break;
                    case 1:
                        "06 - 12"
                        break;
                    case 2:
                        "12 - 18"
                        break;
                    case 3:
                    default:
                        "18 - 00"
                        break;
                    }
                }
            }
            Image {
                anchors.horizontalCenter: parent.horizontalCenter
                source: symbolSource
            }
            Text {
                anchors.horizontalCenter: parent.horizontalCenter
                color: "white"
                font.pixelSize: 16
                font.bold: true
                text: precipitation + "mm"
            }
            Text {
                anchors.horizontalCenter: parent.horizontalCenter
                color: "white"
                font.pixelSize: 16
                font.bold: true
                text: temperature + "°C"
            }
        }

        model: weatherModel.model
    }
}

This is followed by the model itself, and a small notice of the data source.

YrWeatherModel {
    id: weatherModel
    place: "Sweden/V%C3%A4stra_G%C3%B6taland/Alings%C3%A5s"
}

Text {
    anchors.bottom: parent.bottom
    anchors.right: parent.right
    anchors.bottomMargin: 5
    anchors.rightMargin: 40
    text: weatherModel.dataSourceNotice
    color: "white"
    font.pixelSize: 16
    font.italic: true
}

Diving into the model itself, we hit the interesting parts. The structure looks like this:

Item {
    id: root

    property alias model: weatherModel
    property int refreshHour: 1     // How often is the model refreshed (in hours)
    property int dataPoints: 6      // How many data points (max) are expected (in 6h periods)
    property string place           // Place, URL encoded and according to Yr web site, e.g. Sweden/V%C3%A4stra_G%C3%B6taland/Alings%C3%A5s
    readonly property string dataSourceNotice: "Data from MET Norway"

    ListModel {
        id: weatherModel
    }

    Timer {
        interval: 3600000 * root.refreshHour
        running: true
        repeat: true
        onTriggered: {
            _innerModel.reload();
        }
    }

    XmlListModel {
        id: _innerModel

        query: "/weatherdata/forecast/tabular/time"

        source: (place.length === 0)?"":("https://www.yr.no/place/" + root.place + "/forecast.xml")

        XmlRole { name: "period"; query: "string(@period)" }
        XmlRole { name: "symbol"; query: "symbol/string(@number)"; }
        XmlRole { name: "temperature"; query: "temperature/string(@value)"; }
        XmlRole { name: "precipitation"; query: "precipitation/string(@value)"; }

        onStatusChanged: {
            // ...
        }
    }
}

As you can see, the model consists of an inner model of the type XmlListModel. This model is refreshed by a timer (don’t refresh too often – you will most likely be auto-banned by Yr). At the top, there is also a ListModel that is the actual model used by the user interface.

The reason for the ListModel to exist is that I wanted to be able to limit how many data points I show. Each data point represents a six hour window, and I’d like 6 of them, i.e. one and a half day of forecasting.

The onStatusChanged handler in the XmlListModel takes care of this in the following for loop:

onStatusChanged: {
    if (status === XmlListModel.Ready)
    {
        for(var i = 0; i< root.dataPoints && i < count; ++i)
        {
            var symbol = get(i).symbol;
            var period = parseInt(get(i).period);
            var is_night = 0;

            if (period === 3 || period === 0)
                is_night = 1;

            weatherModel.set(i, {
               "period":period,
               "symbol":symbol,
               "symbolSource":"https://api.met.no/weatherapi/weathericon/1.1/?symbol=" + symbol + "&is_night=" + is_night + "&content_type=image/png",
                "temperature":get(i).temperature,
                "precipitation":get(i).precipitation
                });
        }
    }
    else if (status === XmlListModel.Error)
    {
        console.warn("Weather error")
        console.warn(errorString());
    }
}

As you can tell, this code has *very* limited error handling. It is almost as it has been designed to break, but it works. The code also shows how convenient it is to connect to online services via QML to build simple, reusable, models that can be turned into beautiful user interfaces.

Next time I have some free time, I’ll look at interfacing with the public transport APIs. Then I will have to deal with JSON data and make explicit XmlHttpRequest calls.

Five days left

I use to joke that the last week before foss-north is the worst – everything is done, all that is left is the stress.

This year, we have the broadest program yet. 25 speakers talking about everything from community policies, GPU isolation, blockchain, historical KDE software, retro computers, IoT, Android, SailfishOS, bug triaging, crowd funding, software updates, yocto, home automation, design to sub-atomic particles.

You can still get a ticket (and make sure to bring a friend) at foss-north . Welcome!