Introducing QtMqtt

Recently, we talked about how we’re broadening our offering towards the automation sector. In case you missed it, you can find all relevant information here as well as read our blog post here.

One of the biggest challenges in starting an automation project is to build a suitable communication stack. MQTT has received more and more popularity over the last years for managing telemetry data (i.e. collecting data from sensors, health status of devices etc.). This is why we are now extending our portfolio to further help and simplify the development workflow.

What is MQTT

MQTT describes itself as follows:

It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium.”

Using a publisher-subscriber methodology puts the routing responsibility towards the server (or in this context called “message broker”), which all clients connect to. Multiple levels of service quality can be specified to guarantee message delivery.

The connection itself usually builds on top of a TCP connection. However, it can use any ordered, lossless and bi-directional communication method.

How QtMqtt Fits Into the Picture

QtMqtt is a client implementation, which can be used for creating devices to send, but also to monitor solutions for receiving and managing data. QtMqtt does not focus on the broker side.

One important item to mention is that we aim to have QtMqtt fully specification compliant compared to other solutions. This implies support for

  • Protocol level 3.1 and 3.1.1 (prominently known/referred as 4)
  • All QoS levels
  • Wildcards
  • Authentication
  • SSL connections
  • Last Will support

Let ‘s dig a bit deeper and discuss how you actually use QtMqtt in your project.

Publishing data:

QMqttClient publisher;
publisher.setHostname(“some.brokerlocation.com”);
publisher.setPort(1883);
publisher.connectToHost();

publisher.publish(“sensor_1/dataset/foo”, “values”, qosLevel);

Receiving data:
QMqttClient subscriber;
subscriber.setHostname(“some.brokerlocation.com”);
subscriber.setPort(1883);
subscriber.connectToHost();
. . .
QSharedPointer<QMqttSubscription> sub = subscriber.subscribe(“sensor_1/#”, qosLevel);
connect(sub.data(), &QMqttSubscription::messageReceived, [&](QMqttMessage msg) {
qDebug() << “New Message:” << msg.payload();
});

Security

It is crucial for any automation solution today to make sure that all communication is secure and safe. QtMqtt provides two means to achieve this:

  1. Authentication via username and password when a connection is established.
  2. Using SSL/TLS sockets as connection channel.

For the latter case, we can utilize QSslSocket as provided by Qt Network. As a convenience, QMqttClient has another member called connectToHostEncrypted() which behaves similar to QSslSocket‘s argument list.

Extending QtMqtt

While MQTT is mostly used via TCP, it isn’t hardwired to it. QtMqtt allows you to specify additional transport methods, which are based on either QIODevice or QAbstractSocket. This implies that you can create your own transport and pass it over to QMqttClient before establishing a connection.

One concrete example is to use MQTT over websockets, for which Qt provides a separate module. QWebsocket is not based on QAbstractSocket due to different means of sending and receiving data. However, the specification is very clear on how MQTT data has to be pushed via websocket (send as binary data, must fit one datagram, etc.). Hence, a convenience class can be implemented. The specific showcase can be found in the examples of the QtMqtt module.

If you found this post interesting, feel free to get in touch with us and get access to a prerelease version.

The post Introducing QtMqtt appeared first on Qt Blog.

Let There Be More Shapes!

As a follow-up to the previous post about the upcoming new Shape element, I am happy to share that the feature set is going to be bigger than previously expected, and this applies already to the upcoming 5.10 release of Qt.

The initial version of the Shape type only had support for linear gradients. The internal and external feedback indicated however that this felt rather incomplete without radial and conical gradients (especially in the light of these being fully supported by QPainter, meaning the fragment shaders doing the heavy lifting were already available, needing only minor adaptation work). The good news is that the patches for RadialGradient and ConicalGradient are now all merged. (follow the links for doc snapshots, note that these are under QtQuick.Shapes 1.0, not to be confused with the similarly named types in QtGraphicalEffects)

Let’s see these in action! It is by the way worth noting that the code snippets shown in this and the previous post can all be found at this repository.

1. Radial gradient

qmlshapedemo_radial

Shape {
    id: radGradCirc
    anchors.fill: parent
    property real r: 60

    ShapePath {
        strokeWidth: 4
        strokeColor: "red"
        fillGradient: RadialGradient {
            centerX: 100; centerY: 100; centerRadius: 100
            SequentialAnimation on focalRadius { ... }
            SequentialAnimation on focalX { ... }
            SequentialAnimation on focalY { ... }
            GradientStop { position: 0; color: "#ffffff" }
            GradientStop { position: 0.11; color: "#f9ffa0" }
            GradientStop { position: 0.13; color: "#f9ff99" }
            GradientStop { position: 0.14; color: "#f3ff86" }
            GradientStop { position: 0.49; color: "#93b353" }
            GradientStop { position: 0.87; color: "#264619" }
            GradientStop { position: 0.96; color: "#0c1306" }
            GradientStop { position: 1; color: "#000000" }
        }
        strokeStyle: ShapePath.DashLine
        dashPattern: [ 1, 4 ]

        startX: radGradCirc.width / 2 - radGradCirc.r
        startY: radGradCirc.height / 2 - radGradCirc.r
        PathArc {
            x: radGradCirc.width / 2 + radGradCirc.r
            y: radGradCirc.height / 2 + radGradCirc.r
            radiusX: radGradCirc.r; radiusY: radGradCirc.r
            useLargeArc: true
        }
        PathArc {
            x: radGradCirc.width / 2 - radGradCirc.r
            y: radGradCirc.height / 2 - radGradCirc.r
            radiusX: radGradCirc.r; radiusY: radGradCirc.r
            useLargeArc: true
        }
    }
}

2. Conical gradient

qmlshapedemo_conical

Shape {
    id: conGradCirc
    anchors.fill: parent
    property real r: 60

    ShapePath {
        strokeWidth: 4
        strokeColor: "black"
        fillGradient: ConicalGradient {
            centerX: 100; centerY: 100
            NumberAnimation on angle { ... }
            GradientStop { position: 0; color: "#00000000" }
            GradientStop { position: 0.10; color: "#ffe0cc73" }
            GradientStop { position: 0.17; color: "#ffc6a006" }
            GradientStop { position: 0.46; color: "#ff600659" }
            GradientStop { position: 0.72; color: "#ff0680ac" }
            GradientStop { position: 0.92; color: "#ffb9d9e6" }
            GradientStop { position: 1.00; color: "#00000000" }
        }

        // ... the actual shape is the same as in the previous example
    }
}

The post Let There Be More Shapes! appeared first on Qt Blog.

Qt talks at CppCon 2017

The program for CppCon 2017 is now published!

CppCon is the annual conference for the C++ community: five days packed with over 100 talks, as well as inspiring keynotes, panel discussions, hallway chats, fun evening events and much more. CppCon is a project of the Standard C++ Foundation, a not-for-profit organization whose purpose is to support the C++ software developer community and promote the understanding and use of modern, standard C++ on all compilers and platforms.

It's our pleasure to announce that Qt will be a huge presence at this year's CppCon, with a training, a keynote speech, two talks and other open content:

  • On September 23-24, KDAB's Giuseppe D'Angelo will deliver a pre-conference training on programming with QtWidgets. This course focuses entirely on QtWidgets, the set of C++ APIs offered by Qt to build cross-platform desktop applications, running on Windows, Linux and Mac.
  • On September 27, Giuseppe will also talk about how to use Qt C++ Core APIs effectively in the 2017 update of the Effective Qt session.
  • On September 29, Simon Hausmann from The Qt Company will explore what's under the hood of the Qt object model and its features (signals, slots, properties) in his Inside the Qt Object Model session.
  • Last but not least, Lars Knoll (Qt Project Chief Maintainer, CTO of The Qt Company) will deliver a keynote speech. The details have yet to be announced, but it's great to see the C++ community acknowledging the importance of the Qt framework in the C++ ecosystem.

This isn't everything -- stay tuned for more info about other Qt-related content at CppCon, including BOFs, panels and lightning talks. Also, don't forget that on September 30 and October 1, KDAB's Thomas McGuire will explain in his post-conference training how to Debug and Profile C++ Code on Linux.

You can register to CppCon here.

See you in Bellevue!

[training_callout] continue reading

The post Qt talks at CppCon 2017 appeared first on KDAB.

New in Qt 5.10: Diagnostics when breaking QML bindings

Property bindings are one of the most interesting features of the QML language. In QML, when we set a value on a property, the right hand side expression isn't evaluated just once to produce a value, like in a ordinary imperative language.

In particular, if the expression involves other properties, then the property we're setting becomes bound to the properties in the expression: whenever they change their values, then the expression is automatically evaluated again, and the target property value updated.

For instance:

[sourcecode]
import QtQuick 2.0

Rectangle {
width: 100; height: 100

// this is a binding:
color: mouseArea.containsMouse ? "red" : "blue"

MouseArea { id: mouseArea; anchors.fill: parent; hoverEnabled: true }
}
[/sourcecode]

In the snippet above, the color property of the Rectangle is the target of a binding: it is bound to the containsMouse property of the internal MouseArea. When the mouse moves inside or outside of the mouse area, its containsMouse property will change, causing the expression for color to be re-evaluated.

In layman's terms: the rectangle will be red if the mouse cursor is hovering over it, and blue otherwise.

Property bindings allow to build our UIs in a very declarative way: we don't need to write boilerplate "slots" to update our UI elements when some other property changes value. The expression that we can write on the right hand side can be as complex as we want, even involving function calls; the engine will do all the work for us, and will make the binding work as expected.

Breaking property bindings

Sounds too good to be true? Well, property bindings have a limitation: if we use an imperative assignment to set a value on a property, its binding will be lost. For instance, suppose we want the rectangle to turn green when we click over it. This is a possible implementation:

[sourcecode]
import QtQuick 2.0

Rectangle {
width: 100; height: 100

// this is still a binding
color: mouseArea.containsMouse ? "red" : "blue"

MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
parent.color = "green" // oops! breaks binding
}
}
}
[/sourcecode]

In the onClicked signal handler we set the color property to green using an ordinary assignment from imperative JavaScript code. With this code, if we click on the rectangle, and then move the mouse over it and outside it, we'll see that the rectangle doesn't change color any more -- it stays green. This happens because the imperative assignment destroyed the binding, and set the color property to one specific value.

Are broken bindings a problem?

In general, the above example is 100% correct QML code, following the documented QML semantics. Therefore, one cannot claim that such code should be rejected by the QML engine or unconditionally raise warnings.

However, in my experience at KDAB, I have never encountered one single occasion when breaking a binding was intended by the developer. Broken bindings were always caused by accident (during refactorings, not realizing that the original property was bound to something, etc.), or by excessive usage of JavaScript to manage state, instead of using more declarative approaches.

On some occasions, a silent overwriting of a binding with a value did actually introduce a runtime bug, which would then stay latent, maybe for a long time. Debugging such issues could be very challenging, as it is not normally clear what the problem is when reading the QML source code -- the bug would manifest itself only when the JavaScript code containing an imperative assignment is run.

Debugging broken bindings

In order for a developer to be able to more easily track down these cases, KDAB contributed a new feature to the QML engine that will appear in Qt 5.10: the QML engine can now print debugging information whenever a binding is broken.

In order to enable the debug output you just need to enable output for the qt.qml.binding.removal logging category, for instance by exporting the QT_LOGGING_RULES environment variable:

[sourcecode]
export QT_LOGGING_RULES="qt.qml.binding.removal.info=true"
[/sourcecode]

With this variable set, the above example:

[sourcecode]
import QtQuick 2.0

Rectangle {
width: 100; height: 100

color: mouseArea.containsMouse ? "red" : "blue"

MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
parent.color = "green"
}
}
}
[/sourcecode]

now prints this debug message:

[sourcecode]
qt.qml.binding.removal: Overwriting binding on QQuickRectangle::color
at file:///example.qml:13
that was initially bound at file:///example.qml:6:12
[/sourcecode]

As you can see, the message tells us which property was bound, where the binding had been established, and where the imperative statement is that breaks the binding. Pretty much everything we need to debug any issues with broken bindings!

[training_callout] continue reading

The post New in Qt 5.10: Diagnostics when breaking QML bindings appeared first on KDAB.

Qt Visual Studio Tools Version 2.1.2 Beta

After some time working on the integration with Visual Studio 2017, we would now like to make the current status of this work in progress available to users of VS 2017.

We have released a new beta of the Qt Visual Studio Tools, corresponding to version 2.1.2. It is available in the Visual Studio Marketplace and can be installed directly from within Visual Studio 2017 (through the ‘Tools > Extensions and Updates…’ menu). Alternatively, it can be downloaded from this page.

Relative to the previous 2.1.1 beta, version 2.1.2 includes some additional bug fixes:

  • Add new item with VS does not generate the moc
    (reported as QTVSADDINBUG-396)
  • Run moc’ing at every build even if there is no file changed
    (QTVSADDINBUG-410)
  • 2.1.1-beta VSIX installer fails
    (QTVSADDINBUG-460)
  • When opening a pro file with Qt 5.9, unable to create the vcxproj file
    (QTVSADDINBUG-472)

For the moment, version 2.1.2 is only available for Visual Studio 2017. There is also one noteworthy issue: Qt projects will be configured with version 8.1 of the Windows SDK, and building will result in an error if the SDK is not installed. The status of this issue and description of a workaround can be found here.

We will continue working on this and other issues and suggestions reported through bugreports.qt.io with a view to providing an official release of the Qt Visual Studio Tools, which will also be available for Visual Studio 2013 and 2015.

The post Qt Visual Studio Tools Version 2.1.2 Beta appeared first on Qt Blog.

Release 2.12.2: Firebase Realtime Listeners & Qt Creator Designer Icons

V-Play 2.12.2 adds support for Realtime Database Listeners to the Firebase Plugin, which allows your app to get notified whenever your data changes. In addition, the recently improved Qt Creator Designer now comes with icons for all V-Play types to let you distinguish the different components more easily.

V-Play 2.12.2 comes as a free update for all V-Play developers.

Firebase Realtime Database Listeners

Use the Firebase Plugin to store and sync data in realtime across all clients with the Firebase NoSQL Cloud Database.

update-2122-firebase-database-data

The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and changes to the database are propagated to other clients in real time. This update adds new properties and signals to the FirebaseDatabase item, which you can use to add listeners for certain database entries. With the Firebase Realtime Listeners, your app is notified immediately after your data in the cloud gets changed – no matter which device, user or application changed the value.

The following example uses the FirebaseDatabase::realtimeValueKeys property and FirebaseDatabase::realtimeValueChanged() signal to keep track of a public database entry newstext:

import VPlayPlugins 1.0
import VPlayApps 1.0

App {

  FirebaseDatabase {
    realtimeValueKeys: ["public/newstext"]
    onRealtimeValueChanged: {
      if(success) {
        console.debug("Public Realtime Value '" + key + "' changed to '" + value + "'")

        // if newstext got changed -> update AppText to show news
        if(key === "newstext")
          news.text = value
      }
      else {
        console.debug("Error with message: " + value)
      }
    }
  }

  AppText {
    id: news
    text: "" // no news by default, news is loaded from database and always up-to-date
  }
}

This example already shows how powerful the new Firebase Realtime Listeners can be. As soon as the newstext entry changes in the database, all clients will get notified and replace the old news. As Firebase also supports authentication and user access rules, you could even create a real-time chat with this new feature.

 

Firebase Realtime Database vs. V-Play WebStorage

V-Play also comes with its own easy to use WebStorage, which connects to the V-Play backend hosted on Amazon servers (and also available on-premise for Enterprise Customers). It is a simple key-value store which syncs across different devices and platforms via the V-Play Game Network Backend as a Service (BaaS).

So what’s the difference between Firebase and V-Play Cloud Storage?

V-Play WebStorage has these advantages compared to FireBase:

  • All platforms: V-Play WebStorage works not only on iOS & Android, but on all supported V-Play platforms. This also includes Desktop and embedded systems.
  • No authentication required: With V-Play WebStorage, you can access per-user data without your users having to log in.
  • Late authentication: Your users can authenticate later but start saving user data before this authentication. Once they do authenticate, their data is kept and merged to the new user profile.
  • Advanced merge conflict management: With V-Play WebStorage, you can modify the default merge conflict rules that may occur if your user stores to the same key from multiple devices at the same time. In Firebase, the last write is used, whereas in V-Play a merging of the data is tried first. Additionally, you can customize the merge behavior to your requirements with the WebStorage::dataConflictStrategy property.

These are the same features like Firebase has:

  • Offline usage: You can write and read values from the storage even if the user is offline. As soon as the user has Internet Connection again, the locally cached data is synchronized with the cloud.
  • Data synchronization: If the same user is authenticated on multiple devices, a change in the data is forwarded to all connected devices in realtime. This way, the user has the same data across all devices, even across platforms.

There is one restriction with WebStorage though: user access rights. With V-Play WebStorage, there are 2 access rules: per-app and per-user data. The per-user data cannot be shared with other users, and the per-app data cannot restrict its access to certain users. You can work around this restriction by adding custom fields to your per-app data that specifies to which user the app-wide data shall be available for. However, if you have advanced requirements for user rights & data management, the Firebase Realtime Database is the better solution as you can define access rules comprehensively.

For a quick summary: if you are looking for a simple key-value store in the cloud that gets synced to multiple devices, you are better off with the V-Play WebStorage.

 

Note: If you want to build a social messaging app, a chat app, or any application where you’d like to allow your users to become friends with each other, user authentication and send messages, the V-Play Backend (using Game Network + Multiplayer functionality) is an option you can use! It features a friend system, realtime chat with push notifications, cloud storage, and more. Contact us here if you’d like to have a demo project using all these features.

 

Qt Quick Designer Icons

Since V-Play 2.12.1, it is possible to use V-Play Components with the improved Qt Quick Designer of Qt Creator 4.3. To help you get more out of the designer and quickly find the components you need, this update adds icons for all items available with the Qt Quick Designer:

update-2122-designer-icons

For a quick guide how to use the new Qt Quick Designer with V-Play, have a look at our tutorial video:

 

How to Update V-Play

Test out these new features by following these steps:

  • Open the V-Play SDK Maintenance Tool in your V-Play SDK directory.
  • Choose “Update components” and finish the update process to get V-Play 2.12.2 as described in the V-Play Update Guide.

V-Play Update in Maintenance Tool

If you haven’t installed V-Play yet, you can do so now with the latest installer from here. Now you can explore all of the new features included in V-Play 2.12.2!

 

 

More Posts Like This

How to Make Cross-Platform Mobile Apps with Qt – V-Play Apps

How to Make a Qt app

Release 2.11.0: All Monetization Plugins Now Free, Plugin Trial & Firebase Qt Plugin

Release 2_11

WeAreDevelopers Conference App – Open Source & Live Now!

WeAreDevelopers

The post Release 2.12.2: Firebase Realtime Listeners & Qt Creator Designer Icons appeared first on V-Play Engine.

QML vs. HTML5

Guest post by Stefan Larndorfer at sequality

Mobile devices have set the standard in terms of responsiveness and user-friendliness for HMIs across industries. Manufacturers of cars, medical equipment, industrial automation systems and consumer electronics now want to replicate this great user experience for their embedded devices. To find out which technology strategy we should select we set up a test where one of our developers was allocated 160 hours to create a demo application of an embedded system using Qt & QML and same number of hours to create the very equivalent application using HTML5.

Over the past year, more and more customers have been asking us at sequality if they should use HTML5 or Qt using the QML declarative UI language to develop software for embedded devices.

In order to give the most objective advice to our customers, we decided set up a test: give the same developer 160 hours to create a demo of an embedded system using Qt and 160 hours to create the demo using HTML5. These demos would show exactly how the two technologies compare – in terms of development, performance, and sustainability – when used to create the same product. The developer tasked with creating the demos was experienced with using HMTL5 and C++, but had little experience creating user interfaces using Qt and QML. The demos were created independently without any vendor input.

QML vs. HTML 5 test results

The demos showed that although the same amount of development time was spent on both versions, implementation with Qt QML delivered a more functional and complete user interface than the HTML5 version. The testing and debugging process was found to be more straightforward with Qt QML, not least because it didn’t need testing on multiple browsers. In general, the Qt QML version responded more quickly and enabled features, like keyboard and multi-touch, that were not supported by HTML5 without additional implementation.

From an end-user perspective, the Qt QML version behaved exactly as expected regardless of the browser or screen being used to view it.

This is because Qt based applications are compiled for the target, meaning that in terms of user observation, they behave exactly the same no matter which platform they run on. HTML5-based applications, on the other hand, run on the browser of the target, for example Chrome, meaning different platforms can show different behavior as the browser might use different rendering engines depending on the platform.

In terms of the sustainability of the technology, Qt QML is a mature technology that has been developed to ensure backwards compatibility. The AngularJS framework for HTML5 is relatively new, and a valid concern is whether it will be replaced by a new framework in the future. In contrast, QML is very likely to still be supported in 5 years.

Overall, Sequality found that the development of the applications was very different and one needs to carefully consider the benefits and drawbacks of each technology before deciding which one to use.

If the outcome of such an evaluation does not show major advantages of a particular technology, we would recommend Qt over HTML5. In our showcase, the Qt based application was generally faster, more responsive, and easier to implement.

Want to know more?

Download the QML vs. HTML 5 Whitepaper.

Visit us at our booth at Qt World Summit 2017.

 

About

Stefan Larndofer is the CEO and Founder of sequality software engineering. Sequality provides high-quality software engineering services, specializing in user interaction (graphical user interfaces, touch screen software, C++/Qt, embedded Linux) technology. Sequality delivers software with a great user experience, inspired by mobile devices. www.sequality.at

The post QML vs. HTML5 appeared first on Qt Blog.

Cutelyst 1.8.0 released

Cutelyst the Qt Web Framework, has another stable release, this release is mostly filled with bug fixes, the commit log is rather small.

It got fixes on Cutelyst-WSGI to properly work on Windows, QtCreator integration fixes, properly installing dll's on Windows, fix returning the right status from views (this allows you to know if for example View::Email sent the email with success).

Cutelyst is cross-platform, the code builds on CI running on Windows, OSX and Linux, but first class is still UNIX systems, as I don't use Windows, nor have a VM with development configured so I have only ensured it build fine on AppVeyor, Aurel Branzeanu provided some pull requests to improve that, if you also happen to have experience with CMake, MSVC and Windows please help me review or do other pull requests.

The release also got two API additions:

  • Context::setStash(QString, ParamsMultiMap), ParamsMultiMap also known as QMap<QString, QString> is a type used on HTTP query and body parameters, having this method avoid writing ugly code full of QVariant::fromValue()
  • Application::pathTo(QString), instead of using the QStringList version which join the strings to build a path (like the Catalyst does), this just gets the string as you would pass to a QFile, that in turn deals with platform issues.

I'm a bit busy with html-qt and also planning a rewrite of simplemail-qt to be async, so expect smaller Cutelyst releases :)

Again help is welcome (specially on Windows usage).

Get it here https://github.com/cutelyst/cutelyst/archive/v1.8.0.tar.gz

How to Add V-Play to your Qt Mobile App

If you have an existing Qt Mobile App, you can extend your Qt application with V-Play components to improve your mobile app experience. You can mix all of the V-Play and Qt components and have them combined in your project. And the best thing is, you do not need to rewrite your existing Qt application for this! Instead, you can mix the V-Play and Qt components freely in your mobile app. So if you need for example push notifications in your Qt app which uses Qt Quick Controls 2, you can use your existing code and simply add the Google Cloud Messaging (Firebase) push notification plugin by V-Play like this:

import QtQuick 2.0
import QtQuick.Controls 2.0
import VPlayPlugins 2.0

ApplicationWindow {

  GoogleCloudMessaging {
    onNotificationReceived: {
      console.debug("Received push notification: ", JSON.stringify(data))
    }
  }
}

 

This blog post is about the exact steps how you can add V-Play to your Qt Mobile App. Let’s get started.

How does V-Play Improve Qt?

The V-Play SDK for cross-platform apps and games comes with many components to make mobile development with Qt easier. V-Play extends Qt for mobile app development and offers for example:

  • Native look and feel for iOS and Android
  • Monetization with Ads and In-App Purchases
  • Analytics for User Behavior and Crash Reports
  • Push Notifications – triggered locally or by a server
  • Social Engagement with native sharing and Facebook integration
  • Gamification with Highscores, Achievements, Friend System and a Chat
  • Web Backend with cross-platform cloud data storage and syncing between multiple devices
  • Responsive Design for screen and device independence
  • Access to Native Device Features like native dialogs, the camera/image picker, phone contacts or content sharing

 

V-Play Apps Component Showcase iOS V-Play Apps Component Showcase Android

 

Note: To learn more about how V-Play improves Qt for mobile app developers and a comparison between Qt and V-Play, you can also see this page.

It is possible to use all V-Play features in your Qt Quick application, no matter if it is based on Qt Quick Controls 1 or Qt Quick Controls 2. It is even possible to use the V-Play components in your Qt Widget based app – you can contact us here if you’d like to get an example project how to do this.

All V-Play Components can be freely mixed with other QML Items in your mobile app. To make the learning curve easier, V-Play comes with many open-source demo and example projects you can use as a starting point for your own projects.

However, it is not only possible to create V-Play projects from scratch – you can even use V-Play Engine in your existing Qt Quick applications to take advantage of the included features in your Qt app. This article will guide you through all the important steps to successfully use V-Play in your Qt application:

 

Add V-Play to your existing Qt Installation

If you already have Qt 5 installed on your system you can add V-Play to that installation. Navigate to the root SDK folder of your Qt installation and open the executable called Maintenance Tool. Then follow these steps:

1. Choose the Add or remove components option so the Settings button is shown in the bottom left corner.

qt_install_vplay_1

2. Click the Settings button and in the Settings window, click on the Repositories tab.

qt_install_vplay_2

3. Choose the bottom section User defined repositories and click the Add Repository button. Then enter the URL for your development platform in the text box. It is either:

  • https://sdk.v-play.net/2/windows
  • https://sdk.v-play.net/2/macx
  • https://sdk.v-play.net/2/linux

qt_install_vplay_3

4. Next, confirm the V-Play installation repository with OK and proceed with the Add or remove components option by pressing the Continue button.

qt_install_vplay_1

5. V-Play Engine will now show up in addition to the available Qt modules. Make sure that it is checked in the Package Manager and proceed with the MaintenanceTool to install V-Play.
qt_install_vplay_4
Note: Each V-Play version is compatible with a certain Qt version. For example, the current version 2.12.1 uses Qt 5.9.0. If you are using an older or newer version of Qt at the moment, please also check and install the Qt Kits of the version that is compatible with V-Play at this point. V-Play will only be available with the Build Kits that use the correct Qt version. Please have a look at the V-Play Update Guide to view recent changes and Qt version updates of V-Play, and to find out which Qt version is currently used by the latest V-Play version.

Alternatively, you can also download the V-Play installer which comes with the supported Qt version. You can install side-by-side with Qt in a different directory, they will both work independently from each other then.

6. Choose Done when the installation has finished to close the installer.

qt_install_vplay_5

7. You can now open Qt Creator and log-in to your V-Play Account on the new welcome page, which was added by installing V-Play.

qt_install_vplay_6

8. If you do not own a V-Play Account yet, you can create a new account on the V-Play Website. Open the downloads page and choose Download to open the sign-up popup, which will guide you through the registration. As you already added V-Play to your Qt installation, you can skip the actual download after you’ve completed the sign-up.

qt_install_vplay_7

After you’ve successfully installed the V-Play SDK and logged into your V-Play account with Qt Creator, you can start using V-Play in your projects.

Integrate V-Play in your Qt Quick Project

To correctly link and initialize the V-Play components, some additional steps are required for each project that uses V-Play. First, open your Qt Quick Project with Qt Creator. You can then follow these steps to add V-Play:

1. Modify your .pro file configuration to link the V-Play SDK to your project

CONFIG += v-play

2. Open the main.cpp of your project and initialize V-Play

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <VPApplication> // 1 - include VPApplication

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    VPApplication vplay; // 2 - create VPApplication instance

    QQmlApplicationEngine engine;
    vplay.initialize(&engine); // 3 - initialize V-Play

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

3. In your main.qml, use V-Play GameWindow or App as your main ApplicationWindow (this is required for license validation and other checks)

import VPlay 2.0

GameWindow {
  licenseKey: ""
  // ...
}

Alternatively, you can also add a GameWindowItem as a child to your main window instead:

import VPlay 2.0

ApplicationWindow {
    // ...
    GameWindowItem {
      licenseKey: ""
    }
}

4. Add a new file qml/config.json to your project resources, and configure your correct application id and version:

{
    "title": "V-Play App",
    "identifier": "net.vplay.demoapp",
    "orientation": "auto",
    "versioncode": 1,
    "versionname": "1",
    "stage": "test"
}

5. When activating V-Play with a valid license key, the identifier and version of the config.json needs to match the actual app id and version of your mobile app. For Android apps, the identifier and version are configured in the AndroidManifest.xml:

<manifest package="net.vplay.demoapp" android:versionCode="1" … >

If your application does not yet have an Android configuration, you can choose the Projects tab in Qt Creator, select the Android Kit, expand the Build Android APK section and choose Create Templates. This will create a default configuration within a new android subfolder of your project, which also includes the manifest.

6. For iOS, you can set the identifier and version in the Info.plist configuration of your app:

   <key>CFBundleIdentifier</key>
   <string>net.vplay.demoapp</string>
   <key>CFBundleVersion</key>
   <string>1</string>

This configuration file is created by qmake when building for iOS. You can add the following qmake entry to your *.pro configuration to keep and use a custom iOS configuration for your project:

ios {
   QMAKE_INFO_PLIST = ios/Info.plist
}

Make sure to have the correct setting for all three configuration files. If everything looks good, you are ready to use V-Play in your QML application.

You can download this example from GitHub as a reference project too:

Use V-Play Components in your QML Code

Using V-Play in the QML files of your Qt Quick application is easy. All V-Play types are available as QML components and can be used just like any other Item in QML. Mixing V-Play types with Qt components like Qt Quick Controls 2 is also possible.

For example, if you like to add add an easy-to-use local storage to your application, simply add the V-Play import and use the Storage component of V-Play:

import VPlay 2.0

Storage {
  id: localStorage
  property int counter

  onCounterChanged: localStorage.setValue("counter", counter)
  Component.onCompleted: counter = localStorage.getValue("counter") || 0
}

This example saves a counter property in a local SQLite database. The code loads the previous counter value at app start and automatically stores the counter every time it is changed in the app.

It is even possible to use the WebStorage item instead, which utilizes the V-Play Game Network service to synchronize the stored data across devices of the same user:

import VPlay 2.0

VPlayGameNetwork {
  id: gameNetwork
  gameId: <your-vplay-gamenetwork-id>
  secret: "<your-vplay-gameetwork-secret>"
}

WebStorage {
  id: localStorage

  property int counter

  onCounterChanged: localStorage.setValue("counter", counter)
  Component.onCompleted: counter = localStorage.getValue("counter") || 0
}

This is all the code required to include a simple cloud-based data storage.

Other V-Play Components offer the same ease-of-use, for an overview of all available types and features, please have a look at the online documentation of V-Play.

Access Native Device Features in your Qt App

Another big advantage of V-Play is the possibility to use native device features like the camera or confirmation and input dialogs – the NativeUtils component is all you need.

This example shares a custom text and url with the native share dialog on Android and iOS:

import VPlayApps 1.0

App {
AppButton {
  text: "Share!"
  onClicked: nativeUtils.share("V-Play is awesome!", "https://v-play.net")
}
}

Taking a photo with the camera and displaying the shot afterwards is just as simple:

// open camera on button click
AppButton {
  text: "Take Photo"
  onClicked: nativeUtils.displayCameraPicker("Take Photo")
}

// show image after photo was taken
Connections {
  target: nativeUtils
  onCameraPickerFinished: {
    if(accepted) {
      image.source = path
    }
  }
}

AppImage {
  id: image
  anchors.fill: parent
  fillMode: AppImage.PreserveAspectFit
  autoTransform: true
}

When working with dialogs, the V-Play Apps type NativeDialog is also available and offers a more convenient usage to trigger a dialog and handle the response:

AppButton {
   text: "Confirm Dialog"
   onClicked: NativeDialog.confirm("Please Confirm", "Confirm this action?", function(ok) {
     if(ok) {
       // confirmed
     }
     else {
       // not confirmed
     }
   })
 }

Integrate Third-party Services in your Qt Mobile App

V-Play Plugins allow to integrate leading third-party services for ads, analytics, push notifications and more. All native plugins are available to use in your Qt Quick application and offer a convenient way to fast-forward app and game development for iOS and Android.

Since V-Play 2.11.0 it is even possible to fully use V-Play including all monetization plugins with the free Personal Plan of V-Play. Adding services like Google AdMob, Chartboost or Soomla In-App Purchases has never been easier.

plugindemo-admob-android_opt

a. Native Plugin Integration in Qt

With a single import and QML Item, you can for example show an AdMob Banner in your app:

import VPlayPlugins 1.0

AdMobBanner {
  adUnitId: "<your-admob-banner-adUnitId>"
  banner: AdMobBanner.Smart
  anchors.bottom: parent.bottom
}

To actually use the plugin with this simple approach on iOS or Android, a few more steps are required. For example, linking the Android Libraries for Google AdMob with your application requires the following gradle dependency:

allprojects {
  repositories {
      maven { url 'https://sdk.v-play.net/maven/' } // add V-Play repository
  }
}

dependencies {
  compile 'net.vplay.plugins:plugin-admob:2.+' // import admob plugin libraries
}

Just have a look at the plugin documentation of your desired plugin and view the integration steps for more information.

To also prepare the above example for iOS, first copy the GoogleMobileAds.framework from the ios subfolder of the V-Play Plugin Demo on GitHub to a sub-folder called ios within your project. Then add this setting to the qmake configuration in your *.pro file:

ios {
  VPLAY_PLUGINS += admob
}

A short extension to the Project-Info.plist configuration of your iOS app completes the iOS integration steps for using AdMob:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsForMedia</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
</dict>

b. Plugin Activation

Monetization plugins are usable with the free version of V-Play. However, without having a valid V-Play License Key set, only trial-modes are available for all plugins. To be able to set the GameWindowItem::licenseKey with a valid key, let’s first create a new key for the app.

After signing in to your V-Play account, you can create as many keys as you want in the License Key Creation section of the Developers Dashboard. This is how it works:

1. Choose the plugins you want to include in your license key:
plugin-activation-license-1

2. Click on “Generate License Key” and set the app identifier & version code of your application. You can see that the AdMob plugin was enabled in this license key:
plugin-activation-license-2

3. Copy the generated licenseKey to your GameWindowItem, GameWindow, or App component.
plugin-activation-license-3

4. You can now fully use the AdMob plugin on both iOS and Android!

This approach is the same for every plugin and each license key you create allows to activate all the plugins you need. If you encounter any issues when using V-Play in your Qt applications, don’t hesitate to contact us at support@v-play.net or in the support forums.

The full example of this guide also available on GitHub:

 

 

More Posts Like This

 

Release 2.12.1: Visual Editor & Qt Quick Designer Improvements
V-Play Update 2.12.1: Qt Quick Designer Improvements

How to Make Cross-Platform Mobile Apps with Qt – V-Play Apps

How to Make a Qt app

Release 2.11.0: All Monetization Plugins Now Free, Plugin Trial & Firebase Qt Plugin

Release 2_11

WeAreDevelopers Conference App – Open Source & Live Now!

WeAreDevelopers

The post How to Add V-Play to your Qt Mobile App appeared first on V-Play Engine.

clazy 1.2 released

In the previous episode we presented how to uncover 32 Qt best practices at compile time with clazy. Today it's time to show 5 more and other new goodies present in the freshly released clazy v1.2.

New checks

1. connect-not-normalized

Warns when the content of SIGNAL(), SLOT(), Q_ARG() and Q_RETURN_ARG() is not normalized. Using normalized signatures allows to avoid unneeded memory allocations.

Example:

[code lang="cpp"]
// warning: Signature is not normalized. Use void mySlot(int) instead of void mySlot(const int) [-Wclazy-connect-not-normalized]
o.connect(&o, SIGNAL(mySignal(int, int)),
&o, SLOT(void mySlot(const int)));
[/code]

See QMetaObject::normalizedSignature() for more information.

2. returning-data-from-temporary

Warns when returning the data from a QByteArray that will soon be destroyed. Accessing such data usually results in a crash. For example:

[code lang="cpp"]
QByteArray b = ...;
return b.data();
[/code]

[code lang="cpp"]
return funcReturningByteArray().data();
[/code]

[code lang="cpp"]
return funcReturningByteArray().constData();
[/code]

[code lang="cpp"]
const char * getFoo()
{
QByteArray b = ...;
return b; // QByteArray can implicitly cast to char*
}
[/code]

[code lang="cpp"]
const char *c1 = getByteArray();
const char *c2 = str.toUtf8().data();
[/code]

3. install-event-filter

Warns on potential misuse of QObject::installEventFilter().
To install an event filter on obj1 you should call obj1->installEventFilter(this), but sometimes you'll write installEventFilter(obj1) by mistake, which compiles fine.

4. qcolor-from-literal

Warns when a QColor is being constructed from a string literal such as "#RRGGBB".
This is less performant than calling the ctor that takes ints, since it creates temporary QStrings.

Example:

[code lang="cpp"]
QColor c("#000000"); // Use QColor c(0, 0, 0) instead
c.setNamedColor("#001122"); // Use c = QColor(0, 0x11, 0x22) instead
[/code]

5. strict-iterators

Warns when iterator objects are implicitly cast to const_iterator.
This is mostly equivalent to passing -DQT_STRICT_ITERATORS to the compiler, except that it also works for QString. This prevents detachments but also caches subtle bugs such as:

[code lang="cpp"]
QHash<int, int> wrong;
if (wrong.find(1) == wrong.cend()) {
qDebug() << "Not found";
} else {
// find() detached the container before cend() was called, so it prints "Found"
qDebug() << "Found";
}

QHash<int, int> right;
if (right.constFind(1) == right.cend()) {
// Prints "Not Found". This is correct now !
qDebug() << "Not found";
} else {
qDebug() << "Found";
}
[/code]

New features

1. clazy-standalone

Many people asked for clang-tidy support. This can't be done due to clang-tidy not supporting plugins yet. Thus, clazy-standalone was born. It works in a similar way as clang-tidy, by operating on a json compilation database instead of being loaded as a compiler plugin. It can be invoked as:

[code lang="bash"] clazy-standalone -checks=level1 -p compile_commands.json myfile.cpp [/code]

2. ASTMatchers

If you want to contribute a new check to clazy you can now use the AST Matchers API instead of the low level AST way. AST Matchers are gaining popularity and used in many clang tooling already.

3. Pre-built Windows binaries

Since it's an hassle to build LLVM on your own on Windows, we've made a pre-built ready to use
clazy v1.2 package.

The End

That's all folks. You can get clazy from https://phabricator.kde.org/source/clazy/. Be sure to check the README.md file, it should have answers to most (clazy related) questions.

Please try it and report bugs! continue reading

The post clazy 1.2 released appeared first on KDAB.

Qt Creator 4.4 Beta released

We are happy to announce the release of Qt Creator 4.4 Beta!

qtc_inline_annotations

Editing

This version of Qt Creator features optional inline annotations for warnings and errors from the Clang code model and for bookmark comments (Options > Text Editor > Display > Display annotation behind lines). This way, you can easily see the details of issues while you type, without the need to hover your mouse over underlined text or the marker on the left side.

C++

When you rename a symbol, you are now offered to also rename files with the same name. Just trigger the renaming and check “Rename N files” (where “N” will be the number of files with the same base name) in the search results panel before pressing the actual “Replace” button.

If you have the Clang code model enabled, this is now also used for the highlighting of the identifier at the text cursor, which was previously still using the built-in model in any case.

There have been many bug fixes as well. C++ and Qt keywords are no longer wrongly considered keywords in C files, the function signature hint will now work when completing constructors with the Clang code model, and many more.

CMake

We were pretty busy fixing issues already in the 4.3 line of Qt Creator, but there are some improvements in 4.4 as well. We added a filter to the CMake variables setting in build configurations, fixed that headers from the top level directory were not shown in the project tree when using server-mode and improved the handling of CMAKE_RUNTIME_OUTPUT_DIRECTORY in CMake project files.

Other changes

We removed the non-maintained support for Window CE, and changed the ClearCase integration to be disabled by default.

This is just a small selection of the changes and improvements done in 4.4. Please have a look at our change log for a more detailed overview.

Known Issues

QML Profiler can currently get into invalid state. Stopping the application before stopping profiling currently does not work.

Get Qt Creator 4.4 Beta

The opensource version is available on the Qt download page, and you find commercially licensed packages on the Qt Account Portal. Please post issues in our bug tracker. You can also find us on IRC on #qt-creator on chat.freenode.net, and on the Qt Creator mailing list.

The post Qt Creator 4.4 Beta released appeared first on Qt Blog.

New in Qt 5.10: recursive filtering for QSortFilterProxyModel

When using Qt's model/view framework, filtering has always been very easy with QSortFilterProxyModel. To filter a list using text typed by the user in a line-edit, you have certainly been applying the standard recipe:

  1. instantiate the proxy;
  2. insert it between view and source model;
  3. connect the lineedit's textChanged signal to the proxy's setFilterFixedString slot; done!

But what if the model is a tree rather than a flat list?

Let's use the tree below as an example.
base model
As you can see by looking at the highlighted row, there is a toplevel item "Form Editing Mode" containing the item "Layouts", which itself contains an item with the word "Vertical".

Now if we use the same code for filtering as for a flat model, we get a rather unpleasant surprise: typing "Vertical" shows... an empty view.
base model

This is because the toplevel item "Form Editing Mode" doesn't match the filter and therefore it has been filtered out, with no consideration for its children.
This is logical from an implementation point of view (filterAcceptsRow() returns false, the whole subtree is filtered out), but this isn't what we wanted to achieve.

Introducing recursive filtering

We need the parents of matching items to be considered as matching the filter too. Until now this wasn't easily possible.

This is the reason why I implemented (with the help of my colleague Filipe Azevedo) a "recursive filtering" feature in QSortFilterProxyModel. It has just been merged into Qt's dev branch (commit), which means it will be in Qt 5.10. You will need to be a bit patient, but at some point you will be able to make filtering work for tree models by adding one simple line of code:

[code lang="cpp"]
proxy->setRecursiveFiltering(true);
[/code]

And here's the result:
base model

Pretty neat, isn't it?

[training_callout] continue reading

The post New in Qt 5.10: recursive filtering for QSortFilterProxyModel appeared first on KDAB.

QML vs. C++ for application startup time

After 5.8 reduced startup times with its QML compilation caching, object creation remains one of the largest startup time consumer for Qt Quick applications. One can use Loaders to avoid loading parts of the application that are not currently visible, but some scenes with higher complexity can still be taking quite some time to initialize when they urgently need to be displayed, especially on embedded systems.

At QtCon 2016 Andrew Knight presented a few benchmarks showing a situations where C++ can improve Qt Quick object creation times over QML. A conclusion of the session was that those benchmark results would need to be taken with a grain of salt since the specific benefits could be smaller in a real application relatively to everything else happening around.

What we’re presenting today are results of converting parts of a well-known QML example to C++ using public and private APIs, measuring the improvements on loading and execution times to have a better estimate of the opportunity for real world applications.

Preparation

We’re going to use the samegame QML example as reference. This gives us a complete application handling events and producing visual outputs. Like many QML applications reaching initial maturity, focus hasn’t been put on performance optimizations in samegame yet.

Let's start by profiling the application in order to fix the low hanging fruits first. This involves the QML Profiler, but also a regular C++ profiler (like macOS Instruments or Linux perf) together with a "-release -force-debug-info" configured Qt (don't pass -developer-build since it changes the way QML caching behaves). This leads us to remove Qt Quick Particles, QQmlFileSelector, and we’ll also convert property behaviors and states into imperative animations. These changes already considerably improve the performances by reducing the number of QObjects in the scene and by preventing the use of a few less scalable features of Qt Quick.

Most importantly for now, this allows us to focus performance measurements on application code, making sure that both our QML and C++ implementations use the same Qt Quick code paths and total number of QObjects.

Benchmarks

Samegame will be launched in fullscreen when using the eglfs platform plugin, this means that the game area will fill the screen, and on a 1080p display will give us a grid of 60x31 game blocks. We use a Nitrogen6X quad core i.MX6 for this project, running Yocto 2.2 and a standard cross-compiled build of Qt 5.9.1. Running those benchmarks on desktop gave us times around 20x faster, but the relative improvements were similar so we'll focus on i.MX6 results.

Two actions in the application will be uses as reference for our benchmarks:

  • Starting a new game, which uses a thin JavaScript loop to fill the game area with created Block objects.
  • Clicking at a fixed position inside the game area, which is a heavier JavaScript loop that updates the position of all blocks on the right of the clicked column (since the game has been hardcoded to fill each column with the same color, clicking removes one column and move following columns to the left)

The StartGameBenchmark measures creating this scene, the HandleClickBenchmark measures clicking on the left-most row and iterating over all blocks to move them left.

A benchmark has been written inside main() to wrap those functions and execute them multiple times to be able to provide more precise measurements. At multiple stages of the conversion from QML to C++ we will run those two benchmarks and gather results:

  1. The reference QML implementation (with Qt Quick Particles, QQmlFileSelector and declarative animations removed) without any C++:

    // QML
    Block { function fadeIn() { /*...*/ } }
    
    // JavaScript
    block.fadeIn();
    
  2. Only the samegame.js JavaScript Logic code that is run through our benchmarks has been converted to C++:

    // QML
    Block { function fadeIn() { /*...*/ } }
    
    // C++
    QMetaObject::invokeMethod(block, "fadeIn");
    
  3. Block.qml is also implemented in C++ as a QQuickItem subclass. Everything is still connected together using Qt meta-object properties and methods:

    // C++
    class Block : public QQuickItem { Q_INVOKABLE void fadeIn() { /*...*/ } };
    
    // C++
    QMetaObject::invokeMethod(block, "fadeIn");
    
  4. As above, but doing direct C++ method calls rather than going through meta-objects:

    // C++
    class Block : public QQuickItem { void fadeIn() { /*...*/ } };
    
    // C++
    block->fadeIn();
    

Benchmark 1: Starting a new game

Our implementation is using 5 QObjects per block, 2 of which are QQuickItems, for a total of 9300 QObjects. Creating a screen full of blocks for a new game takes 1.153 seconds on our i.MX6 (definitely user-noticeable), but we can reduce it to 0.388 seconds if we create the same item and object structure in C++ (197% faster). The largest gain comes from reimplementing Block.qml in C++ which alone gives us a speed improvement of 124%, mostly because we avoid the evaluation of QML properties and the creation of property bindings during instantiation.

Benchmark 2: Handling a click

This benchmark iterates over the blocks that need to be moved, starts an animation on the x and y property of each block’s root item, and update the blocks board position in the index array. Our C++ implementation is 120% faster but since this action doesn’t create any new QML object, the largest gain comes from reimplementing the JavaScript for-loop in C++, which alone is 57% faster.

The QML JIT implementation usually competes acceptably well with C++ and one thing to note is that the total time for handling this click in our case also has a considerably smaller performance footprint on our application than creation times covered by the Start Game benchmark. So while relatively put this is faster, the user will not notice the 117 ms reduction for Handle Click as much as the 764 ms reduction of the Start Game case.

Why is C++ faster?

Qt Quick and QML are very efficient when it comes to update a scene frame after frame to produce a smooth animation. Properties are consistently and efficiently updated according to animations by property bindings, layout will involve only the necessary elements and the scene graph will reuse as many OpenGL objects as possible to render the new frame, most of the time, with optimal state changes in system and graphics memory.

However, having this structure in place requires some runtime initialization to be done at creation time, and a mostly-dynamically-typed language like QML can’t really compete in this sport with a language like C++, whose design makes performance and compile-time optimizations a top-priority over its other language characteristics.
On top of having to create the same backing C++ QObject and QQuickItem, QML must resolve dynamic types, create data-structures to represent property bindings and go through the Qt meta-object type system to access any native member. Almost all of which C++ performs equivalently at compile time.

One of the reasons why QML can choose to offer conciseness and development speed at the cost of some performance is because it’s also designed to interface well with C++ code. This is an opportunity that, for example, Qt Quick Controls 2 has taken to reduce compilation and creation times with gains comparable to what is presented here. Qt Quick Controls 2 has an advantage over applications though: it’s part of Qt and it has access to private symbols like QQuickText, QQuickRectangle, QQuickFlickable, and even QQuickItemPrivate.

While our C++ implementation is tailored for measuring the potential performance gain of those two specific benchmarks, an ideal method would be if applications could do layout in QML, but handle events and state changes from C++ where the performance gain would be valuable. This could take advantage of strengths of both languages while reducing the number of dynamically-typed property bindings and JavaScript blocks to perform at runtime.
There is still some work to be done in Qt Quick to be able to conveniently harness C++ in UI code. We've already been able to mix the two languages using some hacks for this exercise, but the real blocker at the moment is that we need to be able to create Qt Quick visual primitives like animations, images and rectangles from C++ just like from QML.

Give up binary compatibility?

For this experiment, we had to expose private API that isn’t dynamically exported (i.e. QQuickSpringAnimation). qmake makes it relatively easy to access exported private symbols. This comes at a hefty price: those APIs are not supported and source and binary compatibility are not guaranteed.
An application could theoretically use private APIs without major problems if they are recompiled for any update of Qt. Changes to Qt private API would otherwise likely result in application crashes.

The question is then: should more of the Qt Quick API be publically exposed to C++ application code?

Conclusion

While we demonstrate how using some C++ private Qt Quick APIs can allow you to improve the creation times today, this is unsupported it’s not something that we recommend.

This blog post puts emphasis on creation times, but note that for general performance optimizations we recommend profiling and following the excellent Qt Quick Performance Considerations And Suggestions before considering any unsupported solution.

It should be clear that even though C++ is faster in this case, declarative QML will usually remain a better choice for core UI code because of its flexibility and conciseness. QML is also getting faster every release, this gap will continue shrinking up to a point. As for non-UI business logic, C++ can already be used comfortably without requiring using private Qt Quick APIs.

Long creation times are also not a problem if it can happen while the user is not waiting, this can be accomplished with asynchronous Loaders or by pre-loading components.

To conclude we are asking the community: Are those loading time improvements a great enough opportunity to justify improving the C++ brigde for UI code and extending the public Qt Quick API to classes like animations, QQuickRectangle and QQuickImage? A set of base classes that would give applications a freedom similar to what Qt Quick Controls 2 has.

Contribute to the discussion by letting us know in social medias or comments below if you have experience using C++ for Qt Quick UI code, and/or could benefit from having those functionalities publicly available.

Let There Be Shapes!

One of the new features of the upcoming Qt 5.10 is the introduction of the shapes plugin to Qt Quick. This allows adding stroked and filled paths composed of lines, quadratic curves, cubic curves, and arcs into Qt Quick scenes. While this has always been possible to achieve via QQuickPaintedItem or the Canvas type, the Shape type provides a genuine first-class Qt Quick item that from the scene graph’s perspective is backed by either actual geometry or a vendor-specific GPU accelerated path rendering approach (namely, GL_NV_path_rendering).

shape_tiger
The shapes example, running on an Android tablet

Why is This Great?

  • There is no rasterization involved (no QImage, no OpenGL framebuffer object), which is excellent news for those who are looking for shapes spanning a larger area of a possibly high resolution screen, or want to apply potentially animated transformations to the shapes in the scene.
  • The API is fully declarative and every property, including stroke and fill parameters, path element coordinates, control points, etc., can be bound to in QML expressions and can be animated using the usual tools of Qt Quick. Being declarative also means that changing a property leads to recalculating only the affected sets of the underlying data, something that has been traditionally problematic with imperative painting approaches (e.g. QPainter).
  • There are multiple implementations under the hood, with the front Qt Quick item API staying the same. The default, generic solution is to reuse the triangulator from QPainter’s OpenGL backend in QtGui. For NVIDIA GPUs there is an alternative path using the GL_NV_path_rendering OpenGL extension. When using the software renderer of Qt Quick, a simple backend falling back to QPainter will be used. This also leaves the door open to seamlessly adding other path rendering approaches in the future.

Status and Documentation

Right now the feature is merged to the dev branch of qtdeclarative and will be part of 5.10 onces it branches off. The documentation snapshots are online as well:

(due to some minor issues with the documentation system some types in Particles get cross-linked in the Inherited By section and some other places, just ignore this for now)

The canonical example is called shapes and it lives under qtdeclarative/examples/quick as expected.

Let’s See Some Code

Without further ado, let’s look at some code snippets. The path specification reuses existing types from PathView, and should present no surprises. The rest is expected to be fairly self-explanatory. (check the docs above)

1. A simple triangle with animated stroke width and fill color.

shape1

Shape {
    id: tri
    anchors.fill: parent

    ShapePath {
        id: tri_sp
        strokeColor: "red"
        strokeWidth: 4
        SequentialAnimation on strokeWidth {
            running: tri.visible
            NumberAnimation { from: 1; to: 20; duration: 2000 }
            NumberAnimation { from: 20; to: 1; duration: 2000 }
        }
        ColorAnimation on fillColor {
            from: "blue"; to: "cyan"; duration: 2000; running: tri.visible
        }

        startX: 10; startY: 10
        PathLine { x: tri.width - 10; y: tri.height - 10 }
        PathLine { x: 10; y: tri.height - 10 }
        PathLine { x: 10; y: 10 }
    }
}

2. Let’s switch over to dash strokes and disable fill. Unlike with image-backed approaches, applying transformations to shapes are no problem.

shape2

Shape {
    id: tri2
    anchors.fill: parent

    ShapePath {
        strokeColor: "red"
        strokeWidth: 4
        strokeStyle: ShapePath.DashLine
        dashPattern: [ 1, 4 ]
        fillColor: "transparent"

        startX: 10; startY: 10
        PathLine { x: tri2.width - 10; y: tri2.height - 10 }
        PathLine { x: 10; y: tri2.height - 10 }
        PathLine { x: 10; y: 10 }
    }

    SequentialAnimation on scale {
        running: tri2.visible
        NumberAnimation { from: 1; to: 4; duration: 2000; easing.type: Easing.InOutBounce }
        NumberAnimation { from: 4; to: 1; duration: 2000; easing.type: Easing.OutBack }
    }
}

3. Shape comes with full linear gradient support. This works exactly like QLinearGradient in the QPainter world.

shape3-png

Shape {
    id: tri3
    anchors.fill: parent

    ShapePath {
        strokeColor: "transparent"

        fillGradient: LinearGradient {
            x1: 20; y1: 20
            x2: 180; y2: 130
            GradientStop { position: 0; color: "blue" }
            GradientStop { position: 0.2; color: "green" }
            GradientStop { position: 0.4; color: "red" }
            GradientStop { position: 0.6; color: "yellow" }
            GradientStop { position: 1; color: "cyan" }
        }

        startX: 10; startY: 10
        PathLine { x: tri3.width - 10; y: tri3.height - 10 }
        PathLine { x: 10; y: tri3.height - 10 }
        PathLine { x: 10; y: 10 }
    }

    NumberAnimation on rotation {
        from: 0; to: 360; duration: 2000
        running: tri3.visible
    }
}

4. What about circles and ellipses? Just use two arcs. (note: one ShapePath with two PathArcs is sufficient for a typical circle or ellipse, here there are two ShapePath due to the different fill parameters)

shape4

Shape {
    id: circle
    anchors.fill: parent
    property real r: 60

    ShapePath {
        strokeColor: "transparent"
        fillColor: "green"

        startX: circle.width / 2 - circle.r
        startY: circle.height / 2 - circle.r
        PathArc {
            x: circle.width / 2 + circle.r
            y: circle.height / 2 + circle.r
            radiusX: circle.r; radiusY: circle.r
            useLargeArc: true
        }
    }
    ShapePath {
        strokeColor: "transparent"
        fillColor: "red"

        startX: circle.width / 2 + circle.r
        startY: circle.height / 2 + circle.r
        PathArc {
            x: circle.width / 2 - circle.r
            y: circle.height / 2 - circle.r
            radiusX: circle.r; radiusY: circle.r
            useLargeArc: true
        }
    }
}

5. Speaking of arcs, PathArc is modeled after SVG elliptical arcs. Qt 5.10 introduces one missing property, xAxisRotation.

shape5

Repeater {
    model: 2
    Shape {
        anchors.fill: parent

        ShapePath {
            fillColor: "transparent"
            strokeColor: model.index === 0 ? "red" : "blue"
            strokeStyle: ShapePath.DashLine
            strokeWidth: 4

            startX: 50; startY: 100
            PathArc {
                x: 150; y: 100
                radiusX: 50; radiusY: 20
                xAxisRotation: model.index === 0 ? 0 : 45
            }
        }
    }
}

Repeater {
    model: 2
    Shape {
        anchors.fill: parent

        ShapePath {
            fillColor: "transparent"
            strokeColor: model.index === 0 ? "red" : "blue"

            startX: 50; startY: 100
            PathArc {
                x: 150; y: 100
                radiusX: 50; radiusY: 20
                xAxisRotation: model.index === 0 ? 0 : 45
                direction: PathArc.Counterclockwise
            }
        }
    }
}

6. Quadratic and cubic Bezier curves work as expected. Below is a quadratic curve with its control point animated.

shape6

Shape {
    id: quadCurve
    anchors.fill: parent

    ShapePath {
        strokeWidth: 4
        strokeColor: "black"
        fillGradient: LinearGradient {
            x1: 0; y1: 0; x2: 200; y2: 200
            GradientStop { position: 0; color: "blue" }
            GradientStop { position: 1; color: "green" }
        }

        startX: 50
        startY: 150
        PathQuad {
            x: 150; y: 150
            controlX: quadCurveControlPoint.x; controlY: quadCurveControlPoint.y
        }
    }
}

Rectangle {
    id: quadCurveControlPoint
    color: "red"
    width: 10
    height: 10
    y: 20
    SequentialAnimation on x {
        loops: Animation.Infinite
        NumberAnimation {
            from: 0
            to: quadCurve.width - quadCurveControlPoint.width
            duration: 5000
        }
        NumberAnimation {
            from: quadCurve.width - quadCurveControlPoint.width
            to: 0
            duration: 5000
        }
    }
}

7. The usual join and cap styles, that are probably familiar from QPainter and QPen, are available.

shape7

Shape {
    anchors.fill: parent

    ShapePath {
        strokeColor: "red"
        strokeWidth: 20
        fillColor: "transparent"
        joinStyle: ShapePath.RoundJoin

        startX: 20; startY: 20
        PathLine { x: 100; y: 100 }
        PathLine { x: 20; y: 150 }
        PathLine { x: 20; y: 20 }
    }

    ShapePath {
        strokeColor: "black"
        strokeWidth: 20
        capStyle: ShapePath.RoundCap

        startX: 150; startY: 20
        PathCubic {
            x: 150; y: 150; control1X: 120; control1Y: 50; control2X: 200
            SequentialAnimation on control2Y {
                loops: Animation.Infinite
                NumberAnimation { from: 0; to: 200; duration: 5000 }
                NumberAnimation { from: 200; to: 0; duration: 5000 }
            }
        }
    }
}

Any Downsides?

Does this mean the time has finally come to add hundreds of lines and curves and arcs to every Qt Quick scene out there?

Not necessarily.

Please do consider the potential performance implications before designing in a large number of shapes in a user interface. See the notes in the Shape documentation page.

In short, the most obvious gotchas are the following:

  • [generic backend] Shapes with a lot of ShapePath child objects will take longer to generate the geometry. The good news is that this can be mitigated by setting the asynchronous property to true which, as the name suggests, leads to spawning off worker threads without blocking the main UI. This comes at the cost of the shape appearing only after the non-asynchronous UI elements.
  • [GL_NV_path_rendering backend] Geometry generation is a non-issue here, however due to the way the “foreign” rendering commands are integrated with the Qt Quick scene graph, having a large number of Shape items in a scene may not scale very well since, unlike plain geometry-based scenegraph nodes, these involve a larger amount of logic and OpenGL state changes. Note that one Shape with several ShapePath children is not an issue here since that is really just one node in the scenegraph.
  • Antialiasing is currently covered only through multi or super sampling, either for the entire scene or for layers. Note that Qt 5.10 introduces a very handy property here: layer.samples can now be used to enable using multisample renderbuffers, when supported.
  • Shape is not a replacement for rectangles and rounded rectangles provided by Rectangle. Rectangle will always perform better and can provide some level of smoothing even without multisampling enabled.

Nevertheless we expect Shape to be highly useful to a large number of Qt Quick applications. The Qt 5.10 release is due H2 this year, so…stay tuned!

The post Let There Be Shapes! appeared first on Qt Blog.

Qt WebGL Streaming merged

Some time ago I published a couple of blog posts talking about Qt WebGL Streaming plugin. The time has come, and the plugin is finally merged into the Qt repository. In the meantime, I worked on stabilization, performance and reducing the calls sent over the network. It also changed a bit in the way the connections are handled.

New client approach

In the previous implementations, the client was accepting more than one concurrent connections. After the latest changes, the plugin is going to behave like a standard QPA plugin. Now, only one user per process is allowed. If another user tries to connect to the web server, it will see a fancy loading screen until the previous client disconnects.
The previous approach caused some problems with how the desktop applications and GUI frameworks are designed. Everyone can agree that desktop applications are not intended to work with concurrent physical users, even if the window instances were different for all users.

No more boilerplate code

Previously the application had to be modified to support this platform plugin. This code was needed to make the application work with the plugin:

class EventFilter : public QObject
{
public:
    virtual bool eventFilter(QObject *watched, QEvent *event) override
    {
        Q_UNUSED(watched);
        if (event->type() == QEvent::User + 100) {
            createWindow(true);
            return true;
        } else if (event->type() == QEvent::User + 101) {
            window->close();
            window->deleteLater();
            return true;
        }

        return false;
    }
};

And install the event filter into the QGuiApplication.

No more modifications in applications are needed anymore.

How to try

So, if you want to give it a try before Qt 5.10 is released (~November 2017) do the following:

Prerequisites

Since WebGL was modelled using OpenGLES2 as reference, first thing you will need is to have an OpenGLES2 version of Qt built. To do that, you need to pass the parameter -opengl es2 to the configure before building.
Example:

./configure -opensource -confirm-license -opengl es2

Depending on your system it is possible you will need some aditional headers and libraries to be able to use es2.

Testing the plugin

After building everything, you can try to run a Qt Quick example.

To try the photoviewer example we need to build it and run with the -platform webgl parameters:

./photoviewer -platform webgl

If you want to try the Qt Quick Controls 2 Text Editor:

./texteditor -platform webgl

Supported options

Currently, the plugin only supports an option to configure the port used by the embedded HTTP Server. If you want to listen in the default HTTP port you should write -platform webgl:port=80.

The future

The plugin will be part of Qt 5.10 release as a technology preview (TP), as it needs to be improved. Currently, the plugin contains an HTTP Server and a Web Sockets server to handle the browser connections. I’m planning to remove the servers from the plugin and start using a Lightweight QtHttpServer we are working on right now. Once it’s ready, you will be able to create an application server to launch different process inheriting the web socket to communicate with the browsers. This will allow for supporting more than one concurrent user instead of sharing applications among users.

Note: The plugin only works using the Threaded Render Loop. If you use Windows or a platform using a different render loop ensure you set QSG_RENDER_LOOP environment variable to threaded

The post Qt WebGL Streaming merged appeared first on Qt Blog.

Release 2.12.1: Visual Editor & Qt Quick Designer Improvements

V-Play 2.12.1 adds many improvements to better support Qt Quick Designer with V-Play:

  • All V-Play Core Components are now available in the side bar of the designer, which allows to use Drag’n’Drop for adding V-Play components to your QML files with the designer.
  • When V-Play components are used, the designer now supports rendering all QML items in addition to the V-Play ones.
  • Many components now include dedicated designer styles, which allows to use the designer to create UI mock-ups using V-Play, especially for V-Play Apps components.
  • Along with the new side-by-side editing which uses the Form Editor and Text Editor in a single view, this allows to speed up UI creation with V-Play even more.

Improved Visual Editor & Qt Quick Designer

V-Play is the leading cross-platform tool for mobile development in terms of rapid UI development and easy-of-use. The main reason is that V-Play takes advantage of QML, the declarative language for creating UIs with Qt – and we love it!

While everything works like a charm when coding in QML, the visual editor of Qt Creator always seemed a bit lacking and troublesome in the past. However, the Qt Quick Designer of Qt Creator made some big improvements with the recent updates.

For example, it is now even possible to use the Form Editor and Text Editor side-by-side with Qt Creator 4.3, which allows to design and code at the same time:

Qt Quick Designer V-Play 2.12.1

For more information about Qt Creator 4.3, see here.

Needless to say, this feature is amazing to speed up UI creation with QML even more, which is why we decided to improve V-Play for better support of the Qt Quick Designer. This allows all V-Play users to utilize these new IDE features and take their development to a new level.

Drag’n’Drop and Improved Component Rendering

With this V-Play update, you can fully use the Qt Quick Designer in conjunction with V-Play components.

In addition, we made all V-Play core components available for Drag’n’Drop usage from the side bar of the Qt Quick Designer. To try it out, just import the V-Play module, e.g.

import VPlayApps 1.0

All available QML types then show up in the side bar:

Qt Quick Designer V-Play 2.12.1

For this update, we’ve also added dedicated designer styles for V-Play Components. For the first time, it is now possible to drop V-Play components into the designer view and see a mock-up design of what you are building at the moment.

The preview is based on the iOS look & feel that comes with V-Play, so you don’t even need to run your app to see how it will look like!

We especially focused on better support for V-Play Apps. Here’s a short Youtube tutorial for you to get a quick overview of what’s possible:

V-Play Visual Designer – Highlights Video

In the new video below we create a new V-Play Application from scratch to show what’s possible with the designer. It covers:

  • How to create a new V-Play Application with Qt Creator.
  • A short overview of the Qt Quick Designer and how to enable side-by-side editing.
  • Using the designer to add V-Play Components via Drag’n’Drop.
  • How to layout your items using anchoring.
  • Creating a cross-platform V-Play Application with a native-styled main navigation.
  • Binding properties of a control to the property value of another item.
  • Testing the look & feel of your app on Desktop by switching between themes.

More Fixes & Improvements

Besides the highlights mentioned above, there are many other fixes and improvements for the SDK, for example V-Play Multiplayer Improvements and a new Splash Screen. For a full list of improvements and fixes to V-Play in this update, please check out our change log!

How to Update V-Play

Test out these new features by following these steps:

  • Open the V-Play SDK Maintenance Tool in your V-Play SDK directory.
  • Choose “Update components” and finish the update process to get V-Play 2.12.1 as described in the V-Play Update Guide.

V-Play Update in Maintenance Tool

If you haven’t installed V-Play yet, you can do so now with the latest installer from here. Now you can explore all of the new features included in V-Play 2.12.1!

 

 

More Posts Like This

 

How to Make Cross-Platform Mobile Apps with Qt – V-Play Apps

How to Make a Qt app

Release 2.11.0: All Monetization Plugins Now Free, Plugin Trial & Firebase Qt Plugin

Release 2_11

WeAreDevelopers Conference App – Open Source & Live Now!

WeAreDevelopers

 

The post Release 2.12.1: Visual Editor & Qt Quick Designer Improvements appeared first on V-Play Engine.

Qt Quick Designer – The Coffee Machine

With Qt Creator 4.3 released a month ago, coming with cool new features for Qt Quick Designer, we decided it is time to create an example that shows the complete intended workflow for Qt Quick Designer and establishes good practices.

We implemented the UI of a Coffee Machine following the reference design of a professional designer. The designer also provided all graphical assets as PNG images. In the screenshot, you can see the Resource Browser containing all the provided graphical assets. You can use these graphical assets by drag and drop.

coffee-screenshot
The example is the UI of a coffee machine.

The emphasis for this example lies in a clean separation between imperative logic and the purely declarative visual design which improves the collaboration between designers and front-end developers. The separation between the declarative UI and the implementation allows us to create the visual UI using just Qt Quick Designer, while ensuring that the final result is matching the original design.

This way Qt Quick and Qt Quick Designer will maximize productivity and maintainability.

We created a video that gives an overview of the workflow and the structure of the example. Starting with a reference video from the original designer, we model the different screens using states and QML components. Each screen can be created directly in the Qt Quick Designer following the original reference design.

As seen in the video, in the property tabs you can bind properties to JavaScript expressions which allows to model behavior in a convenient way. For example we have the sliders which adjust the different coffee ingredients levels and then we bind the anchor margins of the graphical elements to JavaScript expressions.

We can define expressions controlling the active states, based on when conditions.

The animations and application logic are implemented in a single QML file. We use alias properties to define an interface between individual screens and components. Maintaining and integrating changes to the UI becomes a lot easier this way.

The source code of the example can be found in the Qt examples repository.

Contact us to learn more and discuss your needs in more detail.

The post Qt Quick Designer – The Coffee Machine appeared first on Qt Blog.

Vulkan Support in Qt 5.10 – Part 3

In the previous posts (part 1, part 2) we covered the introduction and basic Vulkan instance creation bits. It is time to show something on the screen!

QWindow or QVulkanWindow?

If everything goes well, the release of Qt 5.10 will come with at least 5 relevant examples. These are the following (with links to the doc snapshot pages), in increasing order of complexity:

hellovulkancubes_android
The hellovulkancubes example, this time running on an NVIDIA Shield TV with Android 7.0

Checking the sources for these examples reveals one common aspect: they all use QVulkanWindow, the convenience QWindow subclass that manages the swapchain and window-specifics for you. While it will not always be suitable, QVulkanWindow can significantly decrease the time needed to get started with Vulkan rendering in Qt applications.

Now, what if one has to go the advanced way and needs full control over the swapchain and the window? That is perfectly doable as well, but getting started may be less obvious than the well-documented QVulkanWindow-based approach. Let’s take a look.

Using a Plain QWindow + QVulkanInstance

There is currently no simple example for this since things tend to get fairly complicated quite quickly. The Qt sources do provide good references, though: besides the QVulkanWindow sources, there is also a manual test that demonstrates creating a Vulkan-enabled QWindow.

Looking at these revals the main rules for Vulkan-enabled QWindow subclasses:

  • There is a new surface type: VulkanSurface. Any Vulkan-based QWindow must call setSurfaceType(VulkanSurface).
  • Such windows must be associated with a QVulkanInstance. This can be achieved with the previously introduced setVulkanInstance() function.
  • Maintaining the swapchain is left completely to the application. However, a well-behaving implementation is expected to call presentQueued() on the QVulkanInstance right after queuing a present operation (vkQueuePresentKHR).
  • Getting a VkSurfaceKHR must happen through surfaceForWindow().
  • To query if a queue family with in a physical device supports presenting to the window, supportsPresent() can be used, if desired. (like with surfaces, this is very handy since there is no need to deal with vkGetPhysicalDeviceWin32PresentationSupportKHR and friends directly).
  • It is highly likely that any Vulkan-enabled window subclass will need to handle QPlatformSurfaceEvent, QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed in particular. This is because the swapchain must be released before the surface, and with QWindow the surface goes away when the underlying native window is destroyed. This can happen unexpectedly early, depending on how the application is structured, so in order to get a chance to destroy the swapchain at the right time, listening to SurfaceAboutToBeDestroyed can become essential.
  • Understanding exposeEvent() is pretty important as well. While the exact semantics are platform specific, the correct behavior in an exposeEvent() implementation is not: simply check the status via isExposed(), and, if different than before, start or stop the rendering loop. This can, but on most platforms does not have to, include releasing the graphics resources.
  • Similarly, any real graphics initialization has to be tied to the first expose event. Do not kick off such things in the constructor of the QWindow subclass: it may not have a QVulkanInstance associated at that point, and there will definitely not be an underlying native window present at that stage.
  • To implement continous updates to the rendering (which may, depending on your logic, be locked to vsync of course), one of the simplest options is to trigger requestUpdate() on each frame, and then handle QEvent::UpdateRequest in a reimplementation of event(). Note however that on most platforms this is essentially a 5 ms timer, with no actual windowing system backing. Applications are also free to implement whatever update logic they like.

Core API Function Wrappers

What about accessing the Vulkan API? The options are well documented for QVulkanInstance. For most Qt-based applications the expectation is that the core Vulkan 1.0 API will be accessed through the wrapper objects returned from functions() and deviceFunctions(). When it comes to extensions, for instance in order to set up the swapchain when managing it manually, use getInstanceProcAddr().

This is the approach all examples and tests are using as well. This is not mandatory, the option of throwing in a LIBS+=-lvulkan, or using some other wrangler library is always there. Check also the Using C++ Bindings for Vulkan section in the QVulkanInstance docs.

That’s all for now, see you in part 4!

The post Vulkan Support in Qt 5.10 – Part 3 appeared first on Qt Blog.

Qt 5.9.1 Released

I am pleased to announce that Qt 5.9.1 is released today. It contains all the latest bug fixes and improvements from Qt 5.9 branch.

Qt Creator 4.3.1 is included in the Qt 5.9.1 offline installer packages and available via the online installer.

As a patch release Qt 5.9.1 does not add any new functionality, just bug fixes and other improvements. For details of the changes compared to Qt 5.9.0 release, please check the Change files of Qt 5.9.1.

Our intention is to make more frequent patch releases for Qt 5.9 LTS than before. So if your most desired fix is not included in Qt 5.9.1 there will be more patch releases in the coming months.

If you are using the online installer, Qt 5.9.1 and Qt Creator 4.3.1 can be updated using the maintenance tool. Offline packages are available for commercial users in the Qt Account portal and at the qt.io Download page for open-source users.

For users targeting iOS we have identified an issue which can be fixed with an additional iOS patch. We know this is unfortunate, but the alternative was to delay the entire release for over one month. In light of this we thought it would be better to release 5.9.1 today, with a hot patch for iOS.

The post Qt 5.9.1 Released appeared first on Qt Blog.

Qt Creator 4.3.1 released

We are happy to announce the release of Qt Creator 4.3.1. This release contains a range of bug fixes.

Most importantly we fixed a memory leak in code completion, which lead to out-of-memory crashes after a while, especially for users on 32-bit Windows. The new version also includes a multitude of improvements for the CMake integration, fixes running applications on iOS 10.3 devices, and mends some regressions related to the project tree.

For a more detailed overview of the included improvements, take a look at our change log.

Get Qt Creator 4.3.1

The opensource version is available on the Qt download page, and you find commercially licensed packages on the Qt Account Portal. Qt Creator 4.3.1 is also available through an update in the online installer. Please post issues in our bug tracker. You can also find us on IRC on #qt-creator on chat.freenode.net, and on the Qt Creator mailing list.

The post Qt Creator 4.3.1 released appeared first on Qt Blog.

Release 2.12.0: Qt 5.9 & Qt Creator 4.3 Support

V-Play 2.12.0 adds support for Qt 5.9 and the latest Qt Creator 4.3. Qt 5.9 adds many great features like support for gamepads and 3D key frame animations. Qt Creator 4.3 adds a much improved design mode, which allows you to write QML code side-by-side with a visual representation of the code. This allows rapid prototyping of UIs.

V-Play 2.12.0 Improvements

V-Play is now compatible with Qt 5.9 and Qt Creator 4.3, which adds an improved QML Designer. The biggest benefit of the new QML Designer is the new live preview of your QML code. You can have your UI side-by-side with QML code, which allows to further accelerate the development process.

Qt Quick Designer Side by Side Visual and Code

Some of the V-Play components now also support the QML Designer and visual development. The supported components include GameWindow, App, Scene, Page, NavigationStack and also most of the other components are working. With this improvement, you can now adjust component properties with a nice visual editor.

Other improvements of this V-Play release:

  • You can use an improved icon-font handling within games and apps and use the latest FontAwesome version 4.7.0 with the IconType component.
  • The Friends View now has an improved UI. You can use the V-Play friends system within V-Play Multiplayer to allow users to send friend requests and then show the friends in a separate section of the leaderboard. You can also use this friend system to allow sending messages only between accepted friends to prevent spam in your in-app messages. This improvement is live in the released card game One Card! for iOS and Android.
    onecard-menu onecard-game
    Download One Card on iOS Download One Card on Android
  • With the AppButton::textFont property, you can now access and modify all font properties of the text within AppButton.
  • The Component Showcase Demo App configuration for ios/Project-Info.plist now includes the NSContactsUsageDescription entry, which is required for NativeUtils::storeContacts() since iOS 10.
  • Use the new Dialog::autoSize property to decide whether the dialog uses a fixed height or a dynamic height based on the Items you add as dialog content.
  • Incorrect warning for publish builds about using DEPLOYMENTFOLDERS is no longer displayed when QRC is actually used instead. This is relevant when protecting your source code for published apps.

Qt 5.9 Improvements for Mobile App Development

Qt 5.9 added many improvements and was shipped on time. This indicates that the new CI system The Qt Company is now be using yields great results. These are our favorite Qt 5.9 improvements, with a focus for mobile app or game development:

Qt 3D: Animations, Physics Based Rendering (PBR), Level of Detail

Qt 3D got a lot better with the Qt 5.9 release. These are our highlights:

  • You can now use key frame animations! This is an important feature, as it allows you to animate your 3d objects in a dedicated animation tool like Blender or Autodesk Maya, and then import this animation with Qt 3D.
  • A Physics Based Rendering (PBR) material is now available in Qt3DExtras.
  • A new Level of Detail component allows loading different 3D models based on projected screen size or distance. This enables you to have better performance.
  • You can now render Qt Quick 2 scenes to a texture and interact with them in a 3D world.
  • 3D text is available in Qt3DExtras:

Improved QML Performance

Thanks to support for ahead-of-time generation of QML type caches and support for shader program binaries now being cached, the initial application startup time, QML loading time and also view initialization times got improved. Also, the rewritten JavaScript garbage collector yields better performance.

Qt Location and Positioning

  • You can now tilt and rotate maps, both through the APIs and through touch gestures.
  • If you want to overlay items to maps this is now easier too.
  • On iOS, you can now collect positioning data even when the application is in the background.
  • There’s also a new plugin that adds support for Mapbox and both raster and vector tiles, using their OpenGL based map rendering engine:

Mapbox OpenGL Plugin

GamePad Support and More

Qt now supports GamePads which is great for improving controls for games on PC, Android, iOS or tvOS devices. The GamePad support works nicely together with the V-Play TwoAxisController component, which is used in several of the sample games available like our Super Mario like platformer game.

Other improvements like Qt NFC support when running as an Android service or better Qt Charts makes this the best Qt release yet. For a list of all new features in Qt 5.9, see here.

Qt Creator 4.3 Support

The absolute highlight of Qt Creator 4.3 is the new live preview of your QML code in the Qt Quick Designer (alias QML Designer):

Qt Quick Designer - Mixed Design and Edit Mode

 

It allows editing the QML code side by side with the form editor as a preview. In addition to this preview, you can also use the property editor together with the text editor. Qt Quick Designer will always select the item that currently contains the cursor.

So if you just forgot the name of a property or enum, you can now use the property editor instead. With the improved designer, you can now create UIs seamlessly by mixing QML code and visual editing. This really combines the best of two worlds, because you can now stay in the design mode instead of switching between code and design modes.

Internally, we were using the Code editing mode most of the time. We have now changed our workflow and development process to use the designer more and have already experienced a faster development process. We’d highly recommend you to try out the new design mode, it will save you a lot of hours and makes development with QML even better. :)

See here for a detailed list of new Qt Creator 4.3 featuers, and here for a list of Qt Quick Designer improvements.

How to Update V-Play

Test out these new features by following these steps:

  • Open the V-Play SDK Maintenance Tool in your V-Play SDK directory.
  • Choose “Update components” and finish the update process to get V-Play 2.12.0 as described in the V-Play Update Guide.

V-Play Update in Maintenance Tool

  • After updating, remove Qt 5.8 from your installed components: Click on “Add or remove Components” and unselect Qt 5.8. Because V-Play is not compatible with Qt 5.8 anymore, it is best to remove these kits.
  • When you now start Qt Creator, it automatically detects the kits for Qt 5.9, which you can use to build your V-Play projects.
  • To enable one of the new Qt 5.9 kits, click “Projects” on the left side of Qt Creator and enable your desired kit in the section “Build and Run”.

If you haven’t installed V-Play yet, you can do so now with the latest installer from here. Now you can explore all of the new features included in V-Play 2.12.0!

 

For a complete list of the changes to V-Play with this update, please check out our change log!

More Posts Like This

 

How to Make Cross-Platform Mobile Apps with Qt – V-Play Apps

How to Make a Qt app

Release 2.11.0: All Monetization Plugins Now Free, Plugin Trial & Firebase Qt Plugin

Release 2_11

WeAreDevelopers Conference App – Open Source & Live Now!

WeAreDevelopers

 

The post Release 2.12.0: Qt 5.9 & Qt Creator 4.3 Support appeared first on V-Play Engine.

Using Compiler Explorer with Qt

One of my preferred developer tools is a web called Compiler Explorer. The tool itself is excellent and useful when trying to optimize your code.
The author of the tool describes it in the Github repository as:

Compiler Explorer is an interactive compiler. The left-hand pane shows editable C/C++/Rust/Go/D/Haskell code. The right, the assembly output of having compiled the code with a given compiler and settings. Multiple compilers are supported, and the UI layout is configurable (the Golden Layout library is used for this). There is also an ispc compiler for a C variant with extensions for SPMD.

The main problem I found with the tool is, it does not allow to write Qt code. I need to remove all the Qt includes, modify and remove a lot of code…

So I decided to modify the tool to be able to find the Qt headers. To do that first of all, we need to clone the source code:

git clone git@github.com:mattgodbolt/compiler-explorer.git

The application is written using node.js, so make sure you have it installed before starting.

The next step is to modify the options line in etc/config/c++.defaults.properties:

-fPIC -std=c++14 -isystem /opt/qtbase_dev/include -isystem /opt/qtbase_dev/include/QtCore

you need to change /opt/qtbase_dev with your own Qt build path.

Then simply call make in the root folder, and the application starts running on port 10240 (by default).

And the mandatory screenshoots 🙂

screenshot_20170622_152005

screenshot_20170622_152744

The post Using Compiler Explorer with Qt appeared first on Qt Blog.

Digital Instrument Cluster with Qt Quick Designer and Qt Safe Renderer

The growth of reconfigurable digital instrument clusters in the automotive industry is exploding. This is driving a need for high performance graphics technologies, designer tooling and solutions for safety critical systems.

The highly optimized Qt Quick technology is a great fit for creating modern digital clusters. Its plug-able back-end technology supports various rendering methods from OpenGL down through OpenVG to software rendering. This flexibility means you can target a wide range of price/performance points such as the NXP i.MX6 family which ranges from quad core with GPU to single core and no GPU.

For the designer, the Qt Quick Designer allows you to design and prototype the cluster user experience without writing any code. If you do chose to edit the QML code the your changes are immediately reflected in the live preview feature of Qt Quick Designer.

Safety critical operation is a key requirement in digital clusters. To satisfy safety requirements the safety critical functionality is separated from the other parts. What the automotive industry calls tell-tales is the safety critical part, these are the warning lamps for things such as airbag, oil level, engine temperature and brakes. These need to be rendered in a separate software partition that has been certified as designed and implemented per the industry’s relevant standards. The Qt Safe Renderer is our implementation that meets these standards.

But UI designers don’t really want to be bothered by such details. They just want to design the UI as a whole, marking items as safety critical is about the extent of what they need to know. We have added this capability into the Qt Quick language and Qt Quick Designer and to make things even more convenient this is done automatically when using one of Qt’s comprehensive set of ISO 7000 standard icons for warning and other indicators. Qt’s drag-and-drop visual design tooling really simplifies this design flow for adding these icons.

Once the design is complete the build process separates the safety critical UI elements from the main UI.  We use the Qt safe Renderer component to render the safety critical items and also to monitor the operation of the main UI. It is critical that any error in operation of the main UI does not impact the correct rendering of the safety critical items. The Qt Safe Renderer will restart the main UI as appropriate should it detect an error. For more details on the Qt Safe Renderer check out this blog post.

To show how all this comes together we created a video. It shows how to design a digital instrument cluster, deploy it to a device and how the Qt Safe Renderer works in practice.

As you can see, Qt offers tools that make design and prototyping digital instrument clusters intuitive for people who prefer visual design tools over coding. As always with Qt, the full power of QML, the Qt framework and C++ are accessible to create even more complex system logic.

You can get going quickly by looking at the code for the digital instrument cluster example used in the video in the Qt examples repository. Some of the Qt Quick components of the example have backends written in C++ which means they need to be built in order to be available in Qt Quick Designer. To do this, build the project for your desktop platform and in Qt Creator go to Tools > Options > Qt Quick > Qt Quick Designer and enable Use QML emulation layer which is built by the selected. For more details on how to integrate custom QML modules have a look at the Qt documentation here.

Contact us to learn more and discuss your needs in more detail.

The post Digital Instrument Cluster with Qt Quick Designer and Qt Safe Renderer appeared first on Qt Blog.

A tale of 2 curves

As my first subject for this animation blog series, we will be taking a look at Animation curves.

Curves, or better, easing curves, is one of the first concepts we are exposed to when dealing with the subject of animation in the QML space.

What are they?

Well, in simplistic terms, they are a description of an X position over a Time axis that starts in (0 , 0) and ends in (1 , 1). These curves are to be applied to a numerical property. For example, say we want to move the value of X from 0 to 250 over a time period of, say, 5000 ms in a linear fashion (constant speed), we would do something like:

NumberAnimation {
        .....
        property: "x"
        duration: 5000
        easing.type: Easing.Linear
        from:0
        to:250
        .....
    }

And it works relatively well - for reference you can see most of them here.

However there is a limited set of curves, and that poses a problem when trying to achieve more complex animation patterns, probably because no single curve in the above list reflects that complex animation we are trying to describe.
Usually the most common solution will be to reach those by using sequential and parallel animations. This creates, in my experience, a lot of trial and error code that we tend not to be particularly proud of. This is mostly because even describing simple enough animations as, say, kicking a ball that jumps, rolls, bounces and stops, requires a lot of code.  We need to describe the y movement in a sequential animation, an x movement in another parallel animation and the rolling phase in yet another animation stage. The code required to generate this is big, clunky and hard to read, given the nature of multiple parallel and sequential animations running under the same master animation.

On top of that, sequential animations suffer from another, more fundamental limitation: they mostly rely on a "stop" of the motion in order to "start" the next movement when jumping from one curve to the next. Not using this will result in non continuities in the speed variation, spikes, and this will look unnatural (a non smooth speed variation indicates an infinite acceleration, and only infinitely rigid materials can achieve that when colliding with other similar materials, which doesn't happen in nature).   

The speed can be seen as the angle of the curve on each point in the chosen easing curve. The steeper the curve, the faster the movement, so when we have a sequential animation, it is important that, when transitioning from one curve to the next, the end angle of one curve is the same as the start angle for the next. Now, given the limited set of curves we are offered, we will have a hard time matching those, other than for curves that fade/start into a flat angle, aka the motion stops and restarts from one motion to the next.

How can we circumvent that limitation?

Can’t I just use my custom curves?

 

The reality is that you can, and it is relatively simple to do. Let me introduce you to the QML easing Curve Editor: one simple application that can be found in your bin Qt folder, named qmleasing. This helps you create such curves.

 

Here you can see an example of such a curve being created. Notice the ticked smooth flag that enforces that the curve is smooth at the junction of the 2 bezierCurves. This allows us to create far more complex animations, as natural as we can achieve, using this UI. The practical usage of this is achieved by copy pasting the simplified bezier description “[0.33,-0.00625,0.34,1.05,0.52,0.916,0.69,0.778,0.66,0.997,1,1]” into an easing.bezierCurve:

 NumberAnimation {
        .....
        property: "x"
        duration: 5000
        easing.bezierCurve: [0.33,-0.00625,0.34,1.05,0.52,0.916,0.69,0.778,0.66,0.997,1,1]
        from:0
        to:250
        .....
    }

The result will be something like this:

[video width="600" height="250" loop="true" autoplay="true" webm="https://www.kdab.com/wp-content/uploads/stories/sem-título.webm" mp4="https://www.kdab.com/wp-content/uploads/stories/sem-título.mp4" ][/video]

 

The first red square is moving according to a linear animation, and the second blue one is moving according to a, still relativity simple, new curve that we made on the qmleasing application. However, as you explore this, it quickly becomes obvious that what you win in freedom, you lose in control. The nature of the curve time/position is a bit counter-intuitive to your (at least my) thinking of position/speed.

The curve is and needs to be a description of a variable (numerical property) from an initial value (0) to a final value (1) over a time period also (0) to (1).  This curve gets scaled and applied to whatever the time frame you chose in milliseconds and the start and end of the value that you are going to change, so when and if you do loop-like bezier curves, they will make no sense, as time "tends" to just move forwards... You need to think in terms of time and not speed, which means you look at the curve and divide it into multiple columns where the points in the curve represent the scaled position according to your to: and from:.  In fact any animation coordination must be thought of in these terms: you look at the time an "event" occurs and map that as you see fit in the curve. Unfortunately this software lacks the visual tools to do this in a precise fashion .

but...

Hmmm, beziers I can do those.

 

As I was investigating this, it became obvious to me that this opened up room for serious exploitation and manipulation of mathematically/physics-based generated curves, and this will be the subject of the next post. I leave a teaser here in the form of the expected end result...

So, see you soon in the continuation of this specific subject of animation curve manipulation.

[video width="900" height="570" webm="https://www.kdab.com/wp-content/uploads/stories/next.webm" loop="true" mp4="https://www.kdab.com/wp-content/uploads/stories/next1.mp4"][/video]

 

As usual leave your comments below. continue reading

The post A tale of 2 curves appeared first on KDAB.

Vulkan Support in Qt 5.10 – Part 2

In the previous instalment we looked at the background for Qt 5.10’s upcoming Vulkan support. Let’s now start digging out into the details.

Obtaining a Vulkan-Enabled Qt Build

When building Qt from sources on Windows, Linux or Android, Vulkan support is enabled automatically whenever a Vulkan header is detected in the build environment. Windows is handled specially in the sense that the environment variable VULKAN_SDK – set by the LunarG Vulkan SDK – is picked up automatically.

Check the output of configure (also available afterwards in config.summary):

Qt Gui:
  ...
  Vulkan ................................. yes
  ...

If it says no, go to qtbase/config.tests/qpa/vulkan, run make, and see why it did not compile.

As mentioned in part 1, neither the QtGui library nor the platform plugins link directly to libvulkan or similar. Same applies to Qt applications by default. This comes very handy here: a Vulkan-enabled Qt build is perfectly fine for deployment also to systems without any Vulkan libraries. No headache with missing DLLs and such. Naturally, once it turns out Vulkan is not available at runtime, QVulkanInstance::create() will fail and will return false always. It must also be noted that the applications themselves can choose to link to a Vulkan (loader) library, if they have a reason to do so: all it takes is adding LIBS+=-lvulkan or similar to the .pro file.

Getting a Vulkan Instance

In Vulkan all per-application state is stored in a VkInstance object, see the the specification for a detailed overview. In Qt, Vulkan instances are represented by QVulkanInstance. This is backed by a QPlatformVulkanInstance following the usual QPA patterns. The platform plugins, at least the ones that are interested in providing Vulkan support, are expected to provide an implementation for it under the hood. As described earlier, this currently covers windows, xcb and android.

Following the familiar pattern from QWindow and the QOpenGL* classes, QVulkanInstance performs no initialization until create() is called. The loading of the Vulkan library (or the loader library which in turn routes to a vendor implementation) happens only at this point. (with a few exceptions, see below)

The resulting VkInstance can be retrieved via vkInstance().

Quite unsurprisingly, QVulkanInstance allows specifying the usual instance configuration options, like the desired API version, and, most importantly, the list of layers and extensions to enable.

While the Qt APIs allow including unsupported layers and extensions too – since it filters them out automatically – it may still be necessary in some cases to examine the names and versions of all supported layers and extensions. This can be done at any time – even before calling create() – via supportedExtensions() and supportedLayers(). These will naturally trigger an early loading of the Vulkan implementation when needed.

It is worth knowing that the surface-related extensions that are required for basic operation, such as VK_KHR_surface or VK_KHR_win32_surface, are automatically added to the list by Qt, and applications do not have to worry about these.

Typical main() Patterns

In the end the main() function for a Qt application with a Vulkan-capable window (or a Vulkan-capable window embedded into a QWidget hierarchy) will typically look like the following:

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv); // or QApplication when widgets are involved

    const bool enableLogsAndValidation = ...

    QVulkanInstance inst;

    if (enableLogsAndValidation) {
        QLoggingCategory::setFilterRules(QStringLiteral("qt.vulkan=true"));

#ifndef Q_OS_ANDROID
        inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation");
#else // see Android-specifics at https://developer.android.com/ndk/guides/graphics/validation-layer.html
        inst.setLayers(QByteArrayList()
                       << "VK_LAYER_GOOGLE_threading"
                       << "VK_LAYER_LUNARG_parameter_validation"
                       << "VK_LAYER_LUNARG_object_tracker"
                       << "VK_LAYER_LUNARG_core_validation"
                       << "VK_LAYER_LUNARG_image"
                       << "VK_LAYER_LUNARG_swapchain"
                       << "VK_LAYER_GOOGLE_unique_objects");
#endif
    }

    if (!inst.create())
        qFatal("Failed to create Vulkan instance: %d", inst.errorCode());

    MyVulkanWindow w;
    w.setVulkanInstance(&inst);
    w.resize(1024, 768);
    w.show();

    return app.exec();
}

In most cases there will be a single QVulkanInstance. This can live on the stack, but has to be ready before creating the QWindow or QVulkanWindow-derived window objects since they will need to be associated with a QVulkanInstance. (more on this and other window-related topics in part 3)

The logging category qt.vulkan can be very helpful for troubleshooting. When enabled, both QVulkanInstance and, if used, QVulkanWindow will print a number of interesting things on the debug output, during initialization in particular. The hard-coded setFilerRules() call in the code snippet above is not necessarily the best approach always, but works well for platforms where environment variables (QT_LOGGING_RULES) are problematic. On Windows and Linux it is better to control this via the environment or configuration files.

When it comes to output from Vulkan and, first and foremost, the validation layers, QVulkanInstance offers the convenience of automatically redirecting these messages to qDebug. By default VK_EXT_debug_report gets enabled and redirection is active. If this is not desired, set the corresponding flag before calling create().

Working with External Graphics Engines

During the lifetime of the Qt 5.x series, there has been a growing focus on making Qt Quick and the underlying OpenGL enablers more interoperable with foreign engines. This led to productizing QQuickRenderControl, the enhancements to QOpenGLContext for adopting existing native contexts, and similar improvements all over the stack.

In the same spirit QVulkanInstance allows adopting an existing VkInstance. All this takes is calling setVkInstance() before create(). This way every aspect of the VkInstance creation is up to the application or some other framework, and QVulkanInstance will merely wrap the provided VkInstance object instead of constructing a new one from scratch.

That’s all for now, stay tuned for part 3!

The post Vulkan Support in Qt 5.10 – Part 2 appeared first on Qt Blog.

CMlyst 0.3.0 released

CMlyst is a Web Content Management System built using Cutelyst, it was initially inspired by Wordpress and then Ghost. So it's a mixture of both.

Two years ago I did it's first release, and since them I've been slowly improving it, it's been on production for that long providing www.cutelyst.org web site/blog. The 0.2.0 release was a silent one which marks the transition from QSettings storage to sqlite.

Storing content on QSettings is at first quite interesting since it's easy to use but it showed not suitable very fast, first it kept leaving .lock files, then it's not very fast to access so I had used a cache with all data, and a notifier updated that when something changed on the directory, but this also didn't properly triggered QFileSystemWatcher so once a new page was out the cache wasn't properly updated.

Once it was ported to sqlite, I decided to study how Ghost worked, this was mainly due many Qt/KDE developer switching to it. Ghost is quite simplistic, so it was very easy to try to provide something quite compatible with it, porting a Ghost theme to CMlyst requires very little changes due it's syntax being close to Grantlee/Django.

Due porting to sqlite it also became clear that an export/import tool was needed, so you can now import/export it in JSON format, pretty close to Ghost, actually you can even import all you Ghost pages with it, but the opposite won't work, and that's because we store pages as HTML not Markdown, my feeling about markdown is that it is simple to use, convenient to geeks but it's yet another thing to teach users which can simply use a WYSIWYG editor.

Security wise you need to be sure that both Markdown and HTML are safe, and CMlyst doesn't do this, so if you put it on production be sure that only users that know what they are doing use it, you can even break the layout with a not closed tag.

But don't worry, I'm working on a fix for this, html-qt is a WHATWG HTML5 specification parser, mostly complete, but the part to have a DOM, is not done yet, with it, I can make sure the HTML won't break layout and remove unsafe tags.

Feature wise, CMlyst has 80% of Ghost features, if you like it please help add missing features to Admin page.

Some cool numbers

Comparing CMlyst to Ghost can be trick, but it's interesting to see the numbers.

Memory usage:

  • CMlyst uses ~5MB
  • Ghost uses ~120MB

Requests per second (using the same page content)

  • CMlyst 3500/rps (production mode), 1108/rps (developer mode)
  • Ghost 100/rps (production mode)

While the RPS number is very different, on production you can use NGINX cache which would make the slow Ghost RPS not a problem, but that comes to a price of more storage and RAM usage, if you run on an AWS micro instance with 1GB of RAM this means you can have a lot less instances running at the same time, some simple math shows you could have 200 CMlyst instaces vs 8 of Ghost.

Try it!

https://github.com/cutelyst/CMlyst/archive/v0.3.0.tar.gz

Sadly it's also liked soon I'll be forking Grantlee, the lack of maintenance just hit me yesterday (when I was going to release this), Qt 5.7+ has changed QDateTime::toString() to include TZ data which broke Grantlee date filter which isn't expecting that, so I had to do a weird workaround marking date as local to avoid the extra information.