Qt AR: Why and How to Add Augmented Reality to Your Mobile App

Improved AR capabilities for mobile platforms are one of the biggest trends of 2018. Apps with AR features like Yelp, Google Translate or Pokémon GO are only the beginning. Augmented reality allows to create innovative user experiences that support your brand.

Mobile AR is on the Rise! Why?

Since the release of Apple’s ARKit and Google’s ARCore, augmented reality made its way into the mobile market. For example, to make it possible to:

  • Catch virtual monsters in your neighborhood. (Pokemon GO)
  • See restaurant descriptions while you’re walking the street. (Yelp)
  • Translate texts while you view a sign. (Google Translate)

AR Apps: Pokémon GO, Yelp, Google Translate

Those apps mix the real world with computer-generated content. They thus show the user a different reality. In that sense, augmented reality (AR) is quite similar to virtual reality (VR), which is why they are often confused.

Differences between VR and AR

Both technologies can change the way you look at the world. However, they aim towards a different goal. Virtual reality tries to build a simulated environment around the user. It can take you to places you’ve never seen and allows you to enter a new world. When VR does its job right, you will believe that you are actually there. For example, when driving in a virtual reality racing simulator:

Virtual Reality Racing Car

In contrast to VR, augmented reality does not take you to a different place. It enhances the world around you with digital information. For example, to see the route of your navigation system mixed into the real street image while driving in your car.

Wikitude Navigation

The world’s first pedestrian and car navigation system that integrates AR was the Wikitude Navigation app. The app was a revolutionary step forward in the navigation and guidance field and eliminates the need for a map.

Advantages of Immersive Experiences in Mobile Apps and Games

Since Apple launched its app store with 20k apps in 2008, it experienced a rapid growth and now offers more than 3M apps. More than ever, businesses and developers thus thrive to provide unique app experiences that support their brand. They empower users to be creative and connect in order to boost engagement and retention rates.

Mobile AR now allows to create immersive app experiences to surprise and engage the users. Businesses have understood this potential and the International Data Corporation forecast for 2018 even expects worldwide spendings on AR and VR to increase by 95%. Let’s have a look at some innovative AR apps:

Telekom: Lenz – Gorillaz App

Telekom Electronic Beats partnered up with the Gorillaz to create a new dimension in music. The Lenz app transforms magenta surfaces into digital portals which display exclusive Gorillaz content.

Washington Post App: Unesco Heritage

The Washington Post has published another successful AR-enhanced story. This time, the Post’s article promotes all 23 of the UNESCO World Heritage sites situated in the USA. To get readers to learn about, appreciate, and visit these locations, the daily newspaper included an AR feature to get users even more involved with the story.

Augmentors: Real Monster Battles

Following in the footsteps of Pokemon GO, Augmentors is the world’s first cross-platform (iOS & Android) augmented reality game backed by the Bitcoin Blockchain. Players can trade, swop, battle, and train gaming creatures in the real world. Early stage game supporters will be rewarded with unique currency and one-of-a-kind creatures.

Augmented Cocktails: AR in Low-Light Conditions

It can be difficult to provide rich AR experiences in all kinds of situations. For example when dealing with low-light scenarios. City Social in London is known for providing great food, drinks, service and a stunning skyscraper view. With the intention of delighting their customers, even more, they paired with Mustard Design. To create an innovative app that brings their cocktails to life:

Lufthansa AR Aviation Demo

Instead of shipping and installing costly demo equipment to be displayed at trade show exhibitions, Lufthansa Technik is innovatively using augmented reality technology to show their customers detailed installation information and connectivity solutions.

How Does Augmented Reality Work?

The above showcases all rely on the mobile device camera and sensors to track images, objects and scenes of the real world:

  • Telekom recognizes magenta surfaces to replace it with different content.
  • The Washington Post app tracks reader’s surroundings and instantly layers the camera view with virtual animals like a bison.
  • Augmentors combines such Instant 3D Tracking with Image Recognition to bring game cards to live.

Another example app that relies on location-based AR is the Osmino app: A quick scan of your surrounding provides you with a comprehensive listing of all free Wi-Fi hotspots around you:

Wikitude Showcase Osmino

You can integrate some of these  features in your mobile app with Apple’s ARKit and Google’s ARCore. But you also have the option to rely on cross-platform tools which go beyond ARKit and ARCore. In fact, the above showcases are all built with the Wikitude AR SDK.

Why use Wikitude instead of ARKit or ARCore?

Being in the market since 2008, Wikitude bridges the gap between different devices, platforms, and levels of AR support. With a single cross-platform API, it allows over 100,000 developers to integrate AR features across iOS, Android and Windows with a single code base, while having a much higher market reach than ARKit and ARCore.

Advantages of the Wikitude SDK Architecture

Wikitude provides a rich AR experience across platforms. To achieve that, it relies on several abstraction layers:

Wikitude SDK Architecture

The Core Components handle features like Image Recognition and Object/Scene Recognition. Wikitude built the so-called SLAM Engine to offer all AR features across devices and platforms.

In case Apple’s ARKit or Google’s ARCore are available, Wikitude can dynamically switch to these native frameworks instead of its own engine. In addition, Wikitude can also run on iOS, Android and Windows devices that do not have such native support for AR.

So compared to native development with ARKit or ARCore, Wikitude even supports AR on devices that are not able to run native AR features via ARKit or ARCore. This is a huge benefit, because your app is not bound by the market coverage of ARKit or ARCore. See this table for a comparison of ARKit and ARCore supported devices, vs the ones supported by Wikitude:

  • iOS ARKit Device Coverage: 81% (minimum iOS 11.0 + iPhone 6S, iPad 5 and newer models)
  • iOS Wikitude Device Coverage: 92% (iOS 9.0 + iPhone 4, iPad 2 and newer models)
    → Wikitude has + 11% iOS device coverage compared to ARKit
  • Android ARCore Device Coverage: 5% (minimum Android 7.0 + currently about 50 device models out of the thousands in the market)
  • Android Wikitude Device Coverage: 95% (minimum Android 4.4 + most existing device models), which means
    → Wikitude has +90% Android device coverage compared to ARCore

For detailed infos which devices are supported, see the official developer docs by Apple for ARKit supported devices, iOS version market share, and by Google for ARCore supported devices.

So if your goal is to make your app available on as many devices as possible, Wikitude is the go-to solution.

To use Wikitude, you can embed a their augmented reality view into your existing native apps. It is not required to modify other views of your iOS, Windows or Android app. Wikitude also offers several plugins to use their SDK  in conjunction with cross-platform app frameworks like V-Play, via its Qt Plugin.

How to Use the Wikitude AR Plugin in Qt Apps

The Wikitude Qt AR Plugin developed by V-Play offers an API to:

  • Integrate Wikitude in Qt applications, and also
  • into existing or new native applications.

The Wikitude Qt AR plugin builds upon the native APIs of Wikitude and can run augmented reality worlds created with the Wikitude JS API.

If you have an existing or newly developed app based on Qt, you can simply load the Wikitude AR Plugin from QML-based Qt Quick applications or C++-based Qt Widgets applications.

How to Use Image Recognition and 3D Tracking in Your Mobile App

Since the release of V-Play Engine’s Wikitude Plugin you can integrate and use the Wikitude AR SDK in your Qt cross-platform app. It only takes a few lines of code. The examples below show how to run some of the Wikitude AR examples with V-Play.

Wikitude Makes Image Tracking Easy

The following demo code includes everything you need to embed a Wikitude view in your QML app. This example tracks certain images and overlays a transparent video, as if it were part of the image:

import QtQuick.Controls 2.0
import QtQuick 2.0
import VPlayApps 1.0
import VPlayPlugins 1.0

App {
 // name of the Wikitude example to load
 property string example: "11_Video_4_Bonus-TransparentVideo"
 readonly property bool exampleIsLoaded: samplesDl.available

 // NavigationStack can display Pages and adds a NavigationBar
 NavigationStack {
   id: navStack
   // at startup show either arPage or downloadPage, in case the example is not loaded yet
   Component.onCompleted: navStack.push(exampleIsLoaded ? arPage : downloadPage)
 }

 // arPage: Page with a Wikitude view
 property Component arPage: Page {
   title: "AR Example"

   // configure Wikitude view
   WikitudeArView {
     id: arView
     anchors.fill: parent
     arWorldSource: samplesDl.getExtractedFileUrl(example+"/index.html")
     running: true
     cameraPosition: WikitudeArView.BackCamera

     //license key for V-Play QML Live app
     licenseKey: "g0q44ri5X4TwuXQ/9MDYmZxsf2qnzTdDIyR2dWhO6IUkLSLU4IltPMLWFirdj+7kFZOdWAhRUD6fumVXLXMZe6Y1iucswe1Lfa5Q7HhQvPxEq0A7uSU8sfkHLPrJL0z5e72DLt7qs1h25RJvIOiRGDoRc/h/tCWwUdOL6ChDnyJTYWx0ZWRfX8Vh9c9kcuw4+pN/0z3srlwIHPV5zJuB1bixlulM4u1OBmX4KFn+4+2ASRCNI+bk655mIO/Pk3TjtYMrgjFR3+iYHvw1UmaYMVjsrgpcVkbzJCT6QmaW8LejnfXDNLAbZSov64pVG/b7z9IZPFLXxRSQ0MRLudoSDAh6f7wMTQXQsyqGrZeuQH1GSWtfjl/geJYOvQyDI+URF58B5rcKnrX6UZW3+7dP92Xg4npw7+iGrO1M4In/Wggs5TXrmm25v2IYOGhaxvqcPCsAvbx+mERQxISrV+018fPpL8TzR8RTZZ5h7PRfqckZ3W54U1WSiGn9bOj+FjDiIHlcvIAISpPg2Vuq88gLp0HJ5W+A+sVirqmmCyU9GKeV5Faiv62CJy6ANCZ83GGX2rWcIAh1vGOQslMr9ay4Js+rJsVN4SIhCYdw9Em9hSpoZgimnOaszI7zn9EnPwVQgNETgVm7pAZdLkH5hxFoIKOPG2e79ZKKmzlkB/IZigoHZWNDUCFnEHDNFlTZjOEwoPi8DDGfzOEOGngWE7jmp24N7GzAP7e54Y3e48KtmIJ1/U0PFKOoi2Yv0Gh+E1siU5MBf8dLO7y7GafJWJ2oCUqJG0pLb2cgTf9pjkr625BV3XxODRylgqc5/UymTY6l1J0qO43u5hH3zaejng4I9cgieA3Y553rAEafAsfhrRmWsLW/kBdu4KLfY4eQ9z4B0TweW/xsofS0bkIqxalh9YuGBUsUhrwNUY7w6jgC6fjyMhtDdEHAlXC2fW1xLHEvY9CKojLNJQUnA0d5QCa22arI8IK63Jn8Cser9Cw57wOSSY0ruoJbctGdlsr/TySUkayAJJEmHjsH73OdbAztGuMjVq7Y643bTog4P3Zoysc="
   }
 }

 // downloadPage: Page for downloading the Wikitude example at runtime
 // this is only required to retrieve the Wikitude sources for the V-Play QML Live app, Wikitude sources can also be bundled with the app otherwise
 property Component downloadPage: Page {
   title: "AR Example - Download"

   Column {
     anchors.fill: parent
     anchors.margins: dp(12)
     spacing: dp(12)

     AppText {
       text: samplesDl.status === DownloadableResource.UnAvailable
             ? qsTr("Wikitude example requires to be downloaded (~ 2MB)")
             : samplesDl.status === DownloadableResource.Downloading
               ? qsTr("Downloading example... (%1%)").arg(samplesDl.progress)
               : qsTr("Extracting example... (%1%)").arg(samplesDl.progress)
       width: parent.width
     }

     AppButton {
       text: samplesDl.status === DownloadableResource.UnAvailable ? qsTr("Start download") : qsTr("Cancel download")
       onClicked: if(samplesDl.status === DownloadableResource.UnAvailable)
                    samplesDl.download()
                  else samplesDl.cancel()
     }

     ProgressBar {
       width: parent.width
       from: 0
       to: 100
       value: samplesDl.progress
     }
   }
 }

 // component to download additional app resources, like the Wikitude example
 DownloadableResource {
   id: samplesDl
   source: "https://v-play.net/qml-sources/wikitude-examples/"+example+".zip"
   extractAsPackage: true
   storageLocation: FileUtils.DownloadLocation
   storageName: example
   onDownloadFinished: {
     if(error === DownloadableResource.NoError) {
       navStack.clearAndPush(arPage) // open AR page after download is finished
     }
   }
 }
}

 

You can test the Image Tracking AR demo with the image below. It is also found in the Wikitude Plugin documentation.

Wikitude Image Tracking Video Example Surfer

Most of the QML code above is a little overhead to let you instantly preview the example with V-Play QML Live Code Reloading.

What is V-Play QML Live Code Reloading?

It allows you to run and reload apps & games within a second on iOS, Android and Desktop platforms. You can just hit save and the app reloads instantly, without the need to build and deploy again! This is especially useful for AR, which usually requires a lot of on-device testing to tweak settings.

You can also use it to run all the examples listed here from the browser, without having to setup any native SDKs on your PC. Just download the V-Play Live Reload App, for Android or iOS to connect a mobile device.

The code above downloads the configured Wikitude example as zip, extracts the archive, and runs the demo in a Wikitude augmented reality view. Pretty amazing, actually. Go ahead and try it yourself by clicking on one of the “Run this Example” buttons.

The possibility to download assets or code at runtime is a super useful advantage of V-Play. This means that the original app can stay small while additional features are downloaded on demand. However, if the AR part is essential in your own app, you can also bundle the Wikitude code so the AR assets are available without an additional download.

The minimum QML code required thus boils down to a few lines of code:

import VPlayApps 1.0
import VPlayPlugins 1.0

App {
 WikitudeArView {
   id: arView
   anchors.fill: parent
   arWorldSource: Qt.resolvedUrl("assets/11_Video_4_Bonus-TransparentVideo/index.html")
   running: true
   cameraPosition: WikitudeArView.BackCamera
   licenseKey: ""
 }
}

How to Create Wikitude AR Worlds

The Wikitude SDK makes it easy to create such augmented reality views. It builds on web technologies (HTML, JavaScript, CSS) to create so-called ARchitect worlds. These augmented reality experiences are ordinary HTML pages. They use the ARchitect JavaScript API to create objects in augmented reality. That is why the WikitudeArView QML component in the above example has an arWorldSource property. It refers to the index.html of the ARchitect world:

<!DOCTYPE HTML>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <meta content="width=device-width,initial-scale=1,maximum-scale=5,user-scalable=yes" name="viewport">
 <title></title>

 <script src="https://www.wikitude.com/libs/architect.js"></script>
 <script type="text/javascript" src="../ade.js"></script>
 <link rel="stylesheet" href="css/default.css">
</head>
<body>
 <script src="js/transparentvideo.js"></script>
</body>
</html>

It is quite simple, as all the magic happens in the JavaScript code for the Architect world. The above example includes transparentvideo.js, which amounts to only 80 lines of code. This is how the main part for the image tracking and video overlay looks like:

var World = {
 init: function initFn() {
   this.createOverlays();
 },

 // create augmented reality overlays
 createOverlays: function createOverlaysFn() {

   /* Initialize ClientTracker */
   this.targetCollectionResource = new AR.TargetCollectionResource("assets/magazine.wtc", {
     onError: function(errorMessage) {
       alert(errorMessage);
     }
   });

   this.tracker = new AR.ImageTracker(this.targetCollectionResource, {
     onError: function(errorMessage) {
       alert(errorMessage);
     }
   });

   /* initialize video drawable */
   var video = new AR.VideoDrawable("assets/transparentVideo.mp4", 0.7, {
     translate: {
       x: -0.2,
       y: -0.12
     },
     isTransparent: true
   });

   video.play(-1);
   video.pause();

   /* handle video playback when image is tracked */
   var pageOne = new AR.ImageTrackable(this.tracker, "*", {
     drawables: {
       cam: &lbrackvideo&rbrack
     },
     onImageRecognized: function onImageRecognizedFn() {
       video.resume();
     },
     onImageLost: function onImageLostFn() {
       video.pause();
     },
     onError: function(errorMessage) {
       alert(errorMessage);
     }
   });
 }
};

World.init();

See the Wikitude documentation for details of their JavaScript API and step-by-step tutorials.

Wikitude Studio – No Coding Required

For those who are not very comfortable with coding, Wikitude also offers a simple drag-and-drop web editor: Wikitude Studio. It is your one-stop shop for generating and managing target collections, as well as for creating and publishing AR experiences!

Wikitude Studio optimizes your projects for the Wikitude SDK. It minimizes the effort of creating image target collections (wtc files) and object target collections (wto files). The Studio Editor makes it possible to add augmentations to your targets. You can test AR experiences and make them available to clients inside the Wikitude App, or inside your own app built with the Wikitude Plugin.

The Power of Instant Tracking and 3D Rendering

Wikitude is not only simple, it is also powerful. In addition to Image Tracking, it can instantly track the camera (Instant Tracking) or real live objects (Object Tracking). The following demo uses Instant Tracking to put 3D objects into the world:


App {
 // changed configuration to load the instant tracking demo 
 property string example: "05_InstantTracking_4_SceneInteraction"

 // ... 

 // no other changes required, DownloadableResource automatically uses the new example as source
 DownloadableResource {
   source: "https://v-play.net/qml-sources/wikitude-examples/"+example+".zip"
   // ...
 }
}

With 230 lines of JavaScript code, the ARchitect world of this example is simple and short as well.

More Augmented Reality Examples

Do you wanna play around some more? Then go ahead and try one of these examples:

Geo Tracking: POI Radar

// run this demo to get a full QML snippet that downloads and opens the chosen example 
property string example: "10_BrowsingPois_2_AddingRadar"

 

Can be used to:

  • Show Points Of Interest around you, based on the GPS position.
  • For example to implement Augmented Navigation or see infos of Hotels or Restaurants around you.

Gesture Image Tracking

// run this demo to get a full QML snippet that downloads and opens the chosen example 
property string example: "02_AdvancedImageTracking_1_Gestures"

Wikitude Image Tracking Face Example

Can be used to:

  • Drop images, gifs or videos onto an image.
  • For example to let users create and share AR experiences, similar to SnapChat / Instagram video processing with tracked objects.

Snap-To-Screen 3D Model

// run this demo to get a full QML snippet that downloads and opens the chosen example 
property string example: "07_3dModels_4_SnapToScreen"

Wikitude Showcase Snap-to-screen Car

Can be used to:

  • Show additional information or 3D scene when scanning a certain image.
  • For example to enhance your print advertisement in a magazine with AR features:

Media Markt Magazine with Augmented Reality

Wikitude SDK Examples App

The following demo app allows you to to browse all Wikitude SDK Examples from within a single app:


 import QtQuick.Controls 2.0
 import QtQuick 2.0
 import VPlayApps 1.0
 import VPlayPlugins 1.0

 App {
   id: app

   DownloadableResource {
     id: samplesDl
     source: "https://v-play.net/qml-sources/wikitude-examples/WikitudeSdkSamples.zip"
     extractAsPackage: true
     storageLocation: FileUtils.AppDataLocation
     storageName: "WikitudeSdkSamples"
   }

   //samples.json lists all the SDK examples
   readonly property url samplesJsonFileUrl: samplesDl.available ? samplesDl.getExtractedFileUrl("samples.json") : ""
   readonly property string samplesJson: samplesDl.available ? fileUtils.readFile(samplesJsonFileUrl) : "[]"

   //map the JSON file to a list model for ListPage
   readonly property var samplesData: JSON.parse(samplesJson)
   readonly property var samplesModel: samplesData.map(function(category) {
     return [ { isHeader: true, name: category.category_name } ].concat(category.samples)
   }).reduce(function(a, b) { return a.concat(b) }, [])

   Rectangle {
     anchors.fill: parent
     color: "white"
   }

   NavigationStack {
     id: navStack

     ListPage {
       id: examplesListPage

       listView.visible: samplesDl.available

       title: "Wikitude AR Examples"

       model: samplesModel

       delegate: SimpleRow {
         enabled: !modelData.isHeader
         style.backgroundColor: enabled ? Theme.backgroundColor : Theme.secondaryBackgroundColor

         iconSource: modelData.is_highlight ? IconType.star : ""
         icon.color: "yellow"

         text: modelData.name
         detailText: !modelData.isHeader && modelData.path || ""

         onSelected: navStack.push(arPage, { sample: modelData })
       }

       Column {
         visible: !samplesDl.available
         anchors.fill: parent
         anchors.margins: dp(12)
         spacing: dp(12)

         AppText {
           text: samplesDl.status === DownloadableResource.UnAvailable
                 ? qsTr("Wikitude SDK examples need to be downloaded (134 MB)")
                 : samplesDl.status === DownloadableResource.Downloading
                   ? qsTr("Downloading SDK examples... (%1%)").arg(samplesDl.progress)
                   : qsTr("Extracting SDK examples... (%1%)").arg(samplesDl.progress)
           width: parent.width
         }

         AppButton {
           text: samplesDl.status === DownloadableResource.UnAvailable ? qsTr("Start download") : qsTr("Cancel download")
           onClicked: if(samplesDl.status === DownloadableResource.UnAvailable)
                        samplesDl.download()
                      else samplesDl.cancel()
         }

         ProgressBar {
           width: parent.width
           from: 0
           to: 100
           value: samplesDl.progress
         }
       }
     }
   }

   property Component arPage: Page {
     property var sample
     readonly property bool usesGeo: sample.requiredFeatures.indexOf("geo") >= 0

     title: sample.name

     WikitudeArView {
       id: arView

       anchors.fill: parent

       arWorldSource: samplesDl.getExtractedFileUrl(sample.path)
       running: true

       //set this to false to use the device location service
       overrideLocation: !usesGeo

       //license key for V-Play QML Live app
       licenseKey: "g0q44ri5X4TwuXQ/9MDYmZxsf2qnzTdDIyR2dWhO6IUkLSLU4IltPMLWFirdj+7kFZOdWAhRUD6fumVXLXMZe6Y1iucswe1Lfa5Q7HhQvPxEq0A7uSU8sfkHLPrJL0z5e72DLt7qs1h25RJvIOiRGDoRc/h/tCWwUdOL6ChDnyJTYWx0ZWRfX8Vh9c9kcuw4+pN/0z3srlwIHPV5zJuB1bixlulM4u1OBmX4KFn+4+2ASRCNI+bk655mIO/Pk3TjtYMrgjFR3+iYHvw1UmaYMVjsrgpcVkbzJCT6QmaW8LejnfXDNLAbZSov64pVG/b7z9IZPFLXxRSQ0MRLudoSDAh6f7wMTQXQsyqGrZeuQH1GSWtfjl/geJYOvQyDI+URF58B5rcKnrX6UZW3+7dP92Xg4npw7+iGrO1M4In/Wggs5TXrmm25v2IYOGhaxvqcPCsAvbx+mERQxISrV+018fPpL8TzR8RTZZ5h7PRfqckZ3W54U1WSiGn9bOj+FjDiIHlcvIAISpPg2Vuq88gLp0HJ5W+A+sVirqmmCyU9GKeV5Faiv62CJy6ANCZ83GGX2rWcIAh1vGOQslMr9ay4Js+rJsVN4SIhCYdw9Em9hSpoZgimnOaszI7zn9EnPwVQgNETgVm7pAZdLkH5hxFoIKOPG2e79ZKKmzlkB/IZigoHZWNDUCFnEHDNFlTZjOEwoPi8DDGfzOEOGngWE7jmp24N7GzAP7e54Y3e48KtmIJ1/U0PFKOoi2Yv0Gh+E1siU5MBf8dLO7y7GafJWJ2oCUqJG0pLb2cgTf9pjkr625BV3XxODRylgqc5/UymTY6l1J0qO43u5hH3zaejng4I9cgieA3Y553rAEafAsfhrRmWsLW/kBdu4KLfY4eQ9z4B0TweW/xsofS0bkIqxalh9YuGBUsUhrwNUY7w6jgC6fjyMhtDdEHAlXC2fW1xLHEvY9CKojLNJQUnA0d5QCa22arI8IK63Jn8Cser9Cw57wOSSY0ruoJbctGdlsr/TySUkayAJJEmHjsH73OdbAztGuMjVq7Y643bTog4P3Zoysc="

       cameraPosition: sample.startupConfiguration.camera_position === "back"
                       ? WikitudeArView.BackCamera
                       : WikitudeArView.FrontCamera

       cameraResolution: WikitudeArView.AutoResolution
       cameraFocusMode: WikitudeArView.AutoFocusContinuous
     }
   }
 }

What’s the Future for AR?

Augmented reality still has a lot of exciting features and functionalities in store for users, for example with Cloud AR and Multiplayer AR capabilities. Wikitude already offers a cloud-based image recognition service. The latest release, SDK  8, which is supported by the Qt Wikitude Plugin, brought many interesting features like Scene Recognition, Instant Targets or Extended Object Tracking you can now use. And in terms of shared experiences, support workers can display 3D content even though they are remote on another user’s device.

Apple recently introduced their new ARKit 2 framework, a platform that allows developers to integrate

  • shared AR, which allows multiplayer augmented reality experiences
  • persistent experiences tied to a specific location
  • object detection and
  • image tracking to make AR apps even more dynamic.

To showcase the new multiplayer feature, Apple introduced their augmented reality game ‘Swift Shot’:

The use-cases for shared augmented reality are vast, for both mobile games and apps. For example, your AR navigation system could show augmentations that other users placed. You would then also see digital warning signs along the road in addition to the route.

You can also build such multi-user experiences with V-Play Multiplayer. Together with Wikitude, a shared augmented reality experience created with QML + JavaScript is also only a few steps away. V-Play also plans to integrate Qt 3D Rendering with Wikitude’s Native APIs to boost rendering performance even more.

If you have a business request for these cutting-edge features currently in development or if you need assistance in developing an AR experience with high quality standards, don’t hesitate to drop a line at support@v-play.net or contact us here. The V-Play SDK is free to use, so make sure to check it out!

 

If you enjoyed this post, please leave a comment or share it on Facebook or Twitter.

More Relevant App Development Resources

The Best App Development Tutorials & Free App Templates

All of these tutorials come with full source code of the mobile apps! You can copy the code to make your own apps for free!

App Development Video Tutorials

Make Cross-Platform Apps with Qt: V-Play Apps

How to Add In-App Chat or Gamification Features to Your Mobile App

How to Make a Mobile App with Qt Quick Designer (QML Designer) & V-Play

 

The post Qt AR: Why and How to Add Augmented Reality to Your Mobile App appeared first on V-Play Engine.

Enterprise Application Development with Velneo and Qt

Do you enjoy case studies? We sure do, especially when those case studies are examples of finest work born from one’s passion for code.

There are many great Qt user stories in desktop applications. One of them comes from Velneo, an innovative Spanish tech company with their development platform that includes a rapid application development tool called Velneo vDevelop, and its application engine.

Despite mobile and web apps being all the rage, desktop applications stay highly relevant in the enterprise market. Native desktop applications beat web apps in performance and far superior user experience regularly. Thousands of Velneo users will attest.

Velneo vDevelop is the visual editor following the WYSIWYG approach. It’s developed using Qt Widgets and other Qt components. In addition, Velneo has developed their own easy and simple-to-learn programming language that saves users from complex implementation details. Velneo vDevelop and the programming language are the main ingredients that let you cook powerful applications – fast and easy.

With the framework, users can create finished software that uses Qt Quick, Qt Widgets, and several other modules. The runtime uses Qt modules that open up various ways to meet user demands in this market.

See below some of the vDevelop editor screenshots.

velneo_vdevelop_screen_01

velneo_vdevelop_screen_02

velneo_vdevelop_screen_03

Check out this video for many examples of ERP, CRM, accounting, and other business applications built with Velneo and Qt. How many different Qt Widgets can you spot? 🙂

To learn more about how Velneo is using Qt, read the case study in our Built with Qt section. If you have any questions about desktop application development, get in touch!

The post Enterprise Application Development with Velneo and Qt appeared first on Qt Blog.

Post Akademy

So, it has been a busy week of Qt and KDE hacking in the beautiful city of Vienna.
Besides getting quite some of the Viennese staple food, schnitzel, it was an interesting adventure of getting smarter.

  • Getting smarter about making sure what happens in North Korea doesn’t stay in North Korea
  • Getting smarter about what is up with this newfangled Wayland technology and how KDE uses it
  • Getting smarter about how to Konquer the world and welcoming new contributors
  • Getting smarter about opensource licensing compliance
  • Getting smarter about KItinerary, the opensource travel assistant
  • Getting smarter about TNEF, a invitation transport format that isn’t that neutral
  • Getting smarter about Yocto, automotive and what KDE can do

And lots of other stuff.

Besides getting smarter, also getting to talk to people about what they do and to write some patches are important events.
I also wrote some code. Here is a highlight:

And a lot of other minor things, including handling a couple of Debian bugs.

What I’m hoping to either put to my own todolist, or preferably others, is

I felt productive, welcome and … ready to sleep for a week.

Python Extensions in QtCreator

Hello world! My name is Tilman and I have been an intern with The Qt Company in Berlin for the last few weeks. During my time here, I have worked on enabling Python extensibility for the QtCreator and I am happy to announce, that a first proof of concept version is available today!

So, what exactly do the Python extensions do?  Well, the goal is to eventually be able to do about anything a native C++ plugin could do. But for now, the scope is much narrower and only a very small part of the C++ API is exposed.

screenshot_20180809_160715

A Technical Perspective

The main goal for me was to explore how this vision could be implemented. For now the project focuses on getting the integration and setup right, rather than having as many bindings as possible.

Everything starts with a new QtCreator plugin, which initializes Python bindings and then loads the user provided Python extensions. This is done by executing their Python scripts in an embedded CPython interpreter. Getting this to work requires two main things:

  1. Bindings (and a mechanism for loading bindings only if the relevant plugins are loaded)
  2. A system for discovering, and running Python extensions

 

Generating Bindings

Some of you may be familiar with Qt for Python. This project enables developers to create Qt applications in Python by generating Python bindings for Qt’s C++ code. To do this, it uses a binding generator called Shiboken.

To generate the bindings for QtCreators APIs, I used the same tool. This means, that on top of all the QtCreator specific bindings, anything from Qt for Python is also available from Python.

Plugins in QtCreator can be disabled by the user. Thus, we can only expose bindings for the Core plugin and things like the Utils library directly without incurring dependencies. This is quite a harsh restriction on the bindings we can use.

To circumvent this problem, any other QtCreator plugin may provide an additional library, which is then dynamically loaded by the Python extensions plugin as necessary. These libraries will eventually be provided for all plugins maintained by the QtCompany. For now, there is one example of such a library available for the Project Explorer plugin.

The Embedded Interpreter

Python extensions are nothing but a directory containing a main.py file, which represents the entry point of the extension.

My main design goal was to make Python extensions ‘feel’ as if they were normal Python scripts, run from within their extension directory. Since all the extensions run in the same embedded Python, there is a good deal of code devoted to making sure extensions seem isolated, as well as setting the appropriate sys.path for each extension.

This means you can do things like import other files from your extensions directory or mess with sys.path, just like you would with a normal Python program.

If your extensions depend on any other Python modules, there is also a facility for loading these dependencies. By including a requirements.txt, all your dependencies are ‘pip installed’ before your extension is first run. Should you need to do any other setup before your main.py can run, you can also provide an optional setup.py, which is run before, and separately from, your main script.

Closing Words

While a lot of heavy lifting still needs to be done, the main challenges of this project are now solved. If you are interested in trying things out yourself, I highly encourage you to check out the projects git repository. There, you can also have a look at the code and a more in-depth documentation.

On top of the C++ code, build instructions and some initial documentation, you will find several examples of Python extensions that give a taste of what will be possible.

The post Python Extensions in QtCreator appeared first on Qt Blog.

Join us for Squish Days 2018

Squish Days 2018

Join us for Squish Days 2018

Want to learn from our froglogic engineers everything about automated GUI Testing with the Squish GUI Tester and Code Coverage Analysis with Squish Coco?

Join us for a day at the Squish Day in one of the below listed cities. You will learn from our engineers how our tools can be used most efficiently, have the chance for in-depth technical discussions with our engineers and other Squish users and you will learn about the future roadmap of Squish GUI Tester and Squish Coco.

The attendance including drinks and lunch is free.

>> Register here! <<

Locations:

 

Squish Day Cambridge

Date & Time: October 23, 2018 | 09:30 – 16:00
Location: Quy Mill Hotel & Spa
Church Rd, Stow cum Quy, Cambridge CB25 9AF, United Kingdom

   

Agenda:

9:30      Entrance
10:00    Introduction
10:30    Intro, demo and Q&A of Squish for Qt
12:30    Lunch
13:30    Intro, demo and Q&A of Squish Coco
14:30    Product Roadmap and demo of Team Server
15:30    General Q&A
16:00    End

Registration

[contact-form-7]

Past events:

Squish Day Amsterdam

Date & Time: March 27, 2018 | 09:30 – 16:00
Location: Room Mate Aitana Hotel
IJdok 6, 1013 MM Amsterdam, The Netherlands

 

Squish Day Munich

Date & Time: May 15, 2018 | 09:30 – 16:00
Location: Courtyard by Marriott Munich East
Orleansstraße 81-83, 81667 Munich, Germany

 

Squish Day Toulouse

Date & Time: June 5, 2018 | 09:30 – 16:00
Location: Hotel Mercure Toulouse Centre Saint Georges
Rue Saint-Jérôme, 31000 Toulouse, France

 

The post Join us for Squish Days 2018 appeared first on froglogic.

Virtlyst 1.2.0 release

Virtlyst - a Web Interface to manage virtual machines build with Cutelyst/Qt/C++ got a new release.

This new release includes a bunch of bug fixes, most importantly probably being the ability to warn user before doing important actions to help avoid doing mistakes.

Most commits came from new contributor René Linder who is also working on a Bootstrap 4 theme and Lukas Steiner created a dockerfile for it. This is especially cool because Virtlyst repository now has 4 authors while Cutelyst which is way older has only 6.

For the next release I'll also try to add user management (today you have a single admin account, and to add new users that need to be done via SQL) which wasn't available on the original WebVirtMgr project but is surely the most important lacking feature.

Have Fun! https://github.com/cutelyst/Virtlyst/archive/v1.2.0.tar.gz

Release 2.18.0: Update to Qt 5.11.1 with QML Compiler and Massive Performance Improvements

V-Play 2.18.0 adds support for Qt 5.11.1, with all features, improvements and fixes. Major changes to the QML compiler pipeline and QML engine boost the performance of your apps and games. The Qt Quick Compiler is now also available with the open source Qt version. This update also adds several improvements and fixes to V-Play app and game components.

Improved QML and JavaScript Performance on iOS, Android and Desktop

Qt now uses a completely new QML compiler pipeline to compile QML and JavaScript into bytecode. Then JIT is used to compile heavy used functions to assembly code on the fly.

qt-qml-js-compiler-pipeline

Image from www.qt.io

Here are some more details about this great addition:

  • Lots of cleanups and performance improvement to the way function calls and JavaScript scopes are being handled.
  • Improved performance of JS property lookups.
  • A new bytecode format that is very compact, saving memory in many cases.
  • Significantly faster bytecode interpreter than in earlier versions of Qt, in many cases reaching almost the performance of the old JIT.
  • A new JIT that works on top of the bytecode interpreter and only compiles hot functions into assembly.
  • Overall test results show almost a doubling of the JS performance on platforms where JIT can’t be used (iOS and WinRT) compared to 5.10.
  • With the new JIT, JS performance is usually around 10-40% faster than in older Qt versions (depending on the use case).

Qt Quick Compiler for AOT Compilation of QML and JS

You can now use the Qt Quick Compiler in all your apps and games. This was previously limited to only commercial Qt users, but is now also available with the open source Qt version.

To use the Qt Quick Compiler, just add the following line to your .pro file

CONFIG += qtquickcompiler

and enable the qrc resource system as described in your .pro and main.cpp file. This will compile your QML and JavaScript files AOT to bytecode and embed them with your application.

Note for using the resource system: For the Qt Quick Compiler, it is not sufficient to just add the directory names to the resources.qrc file. Instead add all the files that you want to include.

Use the Qt Quick Compiler for a Faster App Start

Qt compiles and caches QML and JS files while your application is running. This results in significantly faster load times of applications, as the cache files are faster to load. However, the initial creation of cache files can still take time, especially when the application starts for the very first time. To avoid that initial step and provide faster start-up times from the very beginning, you can use the Qt Quick Compiler to generate the cache files ahead-of-time, when compiling your application.

You can find more info about this here.

Improved Performance and Reduced CPU Usage with Qt 3D

The update to Qt 5.11.1 also brings performance improvements and a lot of fixes to the Qt 3D module. This makes it even easier to add 3D content in your apps and games.

v-play-3d-cube-rotation-sensor-color-select

import VPlayApps 1.0
import QtQuick 2.9
// 3d imports
import QtQuick.Scene3D 2.0
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
import QtSensors 5.9

App {
  // Set screen to portrait in live client app (not needed for normal deployment)
  onInitTheme: nativeUtils.preferredScreenOrientation = NativeUtils.ScreenOrientationPortrait
          
  RotationSensor {
    id: sensor
    active: true
    // We copy reading to custom property to use behavior on it
    property real readingX: reading ? reading.x : 0
    property real readingY: reading ? reading.y : 0
    // We animate property changes for smoother movement of the cube
    Behavior on readingX {NumberAnimation{duration: 200}}
    Behavior on readingY {NumberAnimation{duration: 200}}
  }
  
  NavigationStack {
    Page {
      title: "3D Cube on Page"
      backgroundColor: Theme.secondaryBackgroundColor
      
      Column {
        padding: dp(15)
        spacing: dp(5)
        
        AppText {
          text: "x-axis " + sensor.readingX.toFixed(2)
        }
        AppText {
          text: "y-axis " + sensor.readingY.toFixed(2)
        }
      }
      
      // 3d object on top of camera
      Scene3D {
        id: scene3d
        anchors.fill: parent
        focus: true
        aspects: ["input", "logic"]
        cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
        
        Entity {
          
          // The camera for the 3d world, to view our cube
          Camera {
            id: camera3D
            projectionType: CameraLens.PerspectiveProjection
            fieldOfView: 45
            nearPlane : 0.1
            farPlane : 1000.0
            position: Qt.vector3d( 0.0, 0.0, 40.0 )
            upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
            viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
          }
          
          components: [
            RenderSettings {
              activeFrameGraph: ForwardRenderer {
                camera: camera3D
                clearColor: "transparent"
              }
            },
            InputSettings { }
          ]
          
          PhongMaterial {
            id: material
            ambient: Theme.tintColor // Also available are diffuse, specular + shininess to control lighting behavior
          }
          
          // The 3d mesh for the cube
          CuboidMesh {
            id: cubeMesh
            xExtent: 8
            yExtent: 8
            zExtent: 8
          }
          
          // Transform (rotate) the cube depending on sensor reading
          Transform {
            id: cubeTransform
            // Create the rotation quaternion from the sensor reading
            rotation: fromAxesAndAngles(Qt.vector3d(1,0,0), sensor.readingX*2, Qt.vector3d(0,1,0), sensor.readingY*2)
          }
          
          // The actual 3d cube that consists of a mesh, a material and a transform component
          Entity {
            id: cubeEntity
            components: [ cubeMesh, material, cubeTransform ]
          }
        }
      } // Scene3D
      
      // Color selection row
      Row {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        spacing: dp(5)
        padding: dp(15)
        
        Repeater {
          model: [Theme.tintColor, "red", "green", "#FFFF9500"]

          Rectangle {
            color: modelData
            width: dp(48)
            height: dp(48)
            radius: dp(5)
            
            MouseArea {
              anchors.fill: parent
              onClicked: {
                material.ambient = modelData
              }
            }
          }
        }
      }
    } // Page
  } // NavigationStack
} // App

Add Turn-by-Turn Navigation with Qt Location

You can use many new features of Qt Location and Maps. With this release you can start experimenting with turn-by-turn navigation. There are also several brand new features available for the Mapbox plugin.

Fixes for Qt Quick Controls

Many controls of the Qt Quick Controls 2 module received fixes, which are also available with the derived V-Play controls. Examples of improved components are ButtonGroup, CheckBox, Combobox, RangeSlider, ScrollBar, Slider, SpinBox and many more.

Qt for Webassembly and Python

With Qt for Webassembly, Qt is working towards filling the last large gaps in cross-platform development, allowing users to target the web and browsers as a platform. The first version has been released as a technology preview.

In addition, to the above, Qt is actively working on supporting Qt on Python.

Create Augmented Reality Apps and Games with Wikitude

As mentioned already in a previous release, you can now create feature-rich Augmented Reality (AR) apps & games with the Wikitude Plugin. You will read more on this amazing addition in another blog post coming soon. Stay tuned!

More Features, Improvements and Fixes

Here is a compressed list of improvements with this update:

For a list of additional fixes, please check out the changelog.

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 this release 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 this release!

For a full list of improvements and fixes to V-Play in this update, please check out the change log!

 

 

 

More Posts Like This

 

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

vplay-2-17-0-firebase-cloud-storage-downloadable-resources-and-more

Release 2.17.0: Firebase Cloud Storage, Downloadable Resources at Runtime and Native File Access on All Platforms

vplay-update-2.16.1-live-client-module-live-code-reloading-custom-cpp

Release 2.16.1: Live Code Reloading with Custom C++ and Native Code for Qt

teaser-iphonex-support-and-runtime-screen-orientation-change-705px

Release 2.16.0: iPhone X Support and Runtime Screen Orientation Changes

The post Release 2.18.0: Update to Qt 5.11.1 with QML Compiler and Massive Performance Improvements appeared first on V-Play Engine.

KDAB Training at Qt World Summit, Boston

On Monday, October 29th as part of Qt World Summit, Boston, KDAB is offering five, one-day courses – two we’re calling Introductory and three Advanced. You can see from the course Description what that means in the context of the course you choose.

All KDAB’s trainers are experts with current working knowledge from diverse projects, so this is a rare opportunity to get a rapid boost to your skillset before the conference and Exhibition on Tuesday 30th. And you can meet our trainers again at KDAB’s stand.

KDAB is proud to be a main sponsor of Qt World Summit Boston and we look forward to seeing you there.

KDAB Training in Boston

Introductory

Effective 3D in Qt with Mike Krus

Multithreading in Qt with Jim Albamont

Advanced

Profiling and Debugging for Linux with David Faure

QML Applications Architecture with André Somers

What’s new in C++17? with Giuseppe D’Angelo

 

All KDAB courses at Qt World Summit are One day.

 

The post KDAB Training at Qt World Summit, Boston appeared first on KDAB.

Python – Tron Demo

For SIGGRAPH, KDAB has been working on a new Qt 3D based demo. We decided that instead of using C++, it would be interesting to try out PySide2 and harness Python to drive the application.

The idea behind this demo is to do with data acquisition of a vehicle’s surrounding environment. Once the data is acquired it can be processed and used to display a 3D scene.

The application is structured in two main parts. On the one hand, we use QtQuick and the Qt 3D QML API to declare the UI and instantiate the 3D scene. On the other hand we use Python for the backend logic, data processing and models and definition of the custom Qt 3D meshes elements we’ll need to use in the UI.

Simulating Data Acquisition

Since this is a demo, we simulate the data that we acquire rather than rely on real data acquisition through sensors.

We simulate only two things:

  • Vehicle position and orientation
  • Road lines

The information for these is obtained by looping around a generated set of road sections.

To define a fake road track, we’ve used cubic bezier curves, each bezier curve defining a road section.

A cubic bezier curve is defined as 2 end points + 2 control points. This allows for a rather compact description of the road section we want our vehicle to travel on.

 

Going from one curve to a full road track

 

Using this tool, we generated the bezier curves with these values:

bezier_curves = [
    [(318, 84), (479, 18), (470, 233), (472, 257)],
    [(472, 257), (473, 272), (494, 459), (419, 426)],
    [(419, 426), (397, 417), (354, 390), (324, 396)],
    [(324, 396), (309, 399), (217, 416), (202, 415)],
    [(202, 415), (157, 412), (116, 278), (114, 263)],
    [(114, 263), (119, 219), (151, 190), (182, 192)],
    [(182, 192), (277, 192), (216, 128), (318, 84)]
]

Notice how each bezier curve starts at the position of the last point of the previous curve. That’s because we want no discontinuity between our road sections.

On each curve, we sample 250 subdivisions to generate raw position data. Given we have 7 curves, that gives us a total of 1750 positions.

In real life our vehicle is only aware of the immediately surrounding environment. In our case, we’ve decided that would be about 100 positions in front of the vehicle and 50 positions at the rear.

Every 16ms, we increase a global index (which goes from 0 to 1750) and select 150 entries starting at our index. From these 150 positions we extrude 4 lines (to make 3 road lanes).

The 50th entry we’ve selected is where we assume our vehicle is.

  • Road section start is positions[0]
  • Road section end is positions[149]
  • Vehicle position is positions[50]

 

Making our track visible through the camera

 

In the 3D view we assume the vehicle is placed in (0, 0, 0). The camera is placed slightly behind the vehicle, its view center being the vehicle. So if positions[49] is where our vehicle actually is in the real world, we actually need to translate back all our positions to minus positions[49]. We also want our vehicle and our camera to rotate as we are going along curves. For that we know that our camera is looking toward -Z (0, 0, -1). We can compute a vector u (vehicle position – road section start) and then find the angle between u and -z using the dot product.

 

In code this translates to simply creating a transform matrix:

road_start_position = self.m_points_at_position[0]
screen_origin_position = self.m_points_at_position[50]

def compute_angle_between_road_section_and_z():
    # We want to look toward -Z
    target_dir = QVector3D(0.0, 0.0, -1.0)
    # Our current dir
    current_dir = (screen_origin_position - road_start_position).normalized()
    # Angle between our two vectors is acos(dot, current_dir, target_dir)
    dot = QVector3D.dotProduct(target_dir, current_dir)
    return acos(dot)

rot_angle = compute_angle_between_road_section_and_z()
self.m_road_to_world_matrix = QMatrix4x4()
# Rotate of rot_angle around +Y
self.m_road_to_world_matrix.rotate(degrees(rot_angle), QVector3D(0.0, 1.0, 0.0))
# Translate points back to origin
self.m_road_to_world_matrix.translate(-screen_origin_position)

 

Then, it’s just a matter of transforming all these positions using the transformation matrix.

3D Rendering

Drawing the road

 

To render the road lines, we have created a new Qt 3D QGeometry subclass.

The python backend generates new buffer data for the road every frame, based on the 150 transformed positions that have been computed. Basically for each 2 positions, a quad made up of 2 triangles is generated to make up one part of a road line. This process is repeated 4 times with an offset on the x-axis for each road line. In turn, this is repeated 150 times so that we have quads for each position and for each line to make up our 3 road lanes.

We just upload these buffers to the GPU by using a Qt 3D QBuffer and setting its data property.

from PySide2.QtCore import Property, Signal, QByteArray
from PySide2.Qt3DCore import Qt3DCore
from PySide2.Qt3DRender import Qt3DRender
from array import array

class RoadLineGeometry(Qt3DRender.QGeometry):

    def __init__(self, parent=None):
        Qt3DRender.QGeometry.__init__(self, parent)
        self.m_position_buffer = Qt3DRender.QBuffer(self)
        self.m_position_buffer.setUsage(Qt3DRender.QBuffer.StaticDraw)

        self.m_position_attribute = Qt3DRender.QAttribute(self)
        self.m_position_attribute.setAttributeType(Qt3DRender.QAttribute.VertexAttribute)
        self.m_position_attribute.setDataType(Qt3DRender.QAttribute.Float)
        self.m_position_attribute.setDataSize(3)
        self.m_position_attribute.setName(Qt3DRender.QAttribute.defaultPositionAttributeName())
        self.m_position_attribute.setBuffer(self.m_position_buffer)

        self.addAttribute(self.m_position_attribute)

    def update(self, data, width):
        # Data is a QByteArray of floats as vec3
        float_data = array('f', data.data())
        transformed_point = [v for i in range(0, len(float_data), 3)
                             for v in [float_data[i] - width / 2.0, 0.0, float_data[i + 2],
                                       float_data[i] + width / 2.0, 0.0, float_data[i + 2]]]
        self.m_position_buffer.setData(QByteArray(array('f', transformed_point).tobytes()))
        self.m_position_attribute.setCount(len(transformed_point) / 3)

Note: in Python the QGeometry::geometryFactory API is unavailable, meaning that we need to update directly our QBuffer data in the frontend.

Drawing the bike

 

As for the bike, it is a .obj model we load and then scale and rotate with a transformation matrix. The scale and rotations are updated as we move through the track so that the bike always aligns with the road.

To load the geometry, a custom .obj loader was written. Regular wireframing techniques usually display triangles if the mesh was exported as triangles (which was the case for us). Our custom loader works around that by analyzing faces described in the .obj file and generating lines to match the faces (we have square faces in our case).

In addition, the bike uses a special FrameGraph. I won’t highlight it in details but instead just give you a rough idea of what it does:

  1.  A first pass is rendered into a texture.
  2. A loop is made
    1. An input texture is then used as a base for a multi pass gaussian blur.
    2. The fragment color is summed up with the previous blur output which ends up creating a Bloom Effect.
    3. input texture for next pass = output texture of this pass

The Tron-like appearance is simply a result of this FrameGraph Bloom effect.

What about PySide2 and Qt 3D?

Using Python and PySide2 instead of C++ to create a Qt 3D-based application has quite a few advantages but also a couple of disadvantages:

  • Pros:
    • You can leverage 90% of the C++ API through the Python bindings
    • You can still use QML for the UI
    • A lot of C++ boilerplate is avoided, prototyping faster
    • Deployment is easy on desktop (pip install pyside2)
  • Cons
    • Qt 3D documentation for the Python is still lacking, tricky to find how to import the namespaces
    • Conversion of some Qt types to Python types is tricky (QByteArray, QVector<QVector3D> …)
    • Deployment is hard on embedded (no arm pyside2 pip release yet)
    • Some odd behaviors and queue invocations (variable having to be printed for some changes to be take into account).

 

Overall it was an enjoyable experience and with the bindings, Python is a real alternative to C++ for most of what regular users might wish to do with Qt 3D.

You can download Qt for Python here.

The post Python – Tron Demo appeared first on KDAB.

qbs 1.12 released

We are happy to announce version 1.12.0 of the Qbs build tool.

What’s new?

Generating Interfaces for Qbs and pkg-config

When distributing software components such as libraries, you’d like to make it as simple as possible for other projects to make use of them. To this end, we have added two new modules: The Exporter.qbs module creates a Qbs module from a product, while the Exporter.pkgconfig module generates a .pc file.

For example:

DynamicLibrary {
    name: "mylib"
    version: "1.0"
    Depends { name: "cpp" }
    Depends { name: "Exporter.qbs" }
    Depends { name: "Exporter.pkgconfig" }
    files: "mylib.cpp"
    Group { 
        fileTagsFilter: "dynamiclibrary"
        qbs.install: true
        qbs.installDir: "lib"
    }
    Group { 
        fileTagsFilter: "Exporter.qbs.module"
        qbs.installDir: "lib/qbs/modules/mylib" 
    }
    Group {
        fileTagsFilter: "Exporter.pkgconfig.pc"
        qbs.install: true
        qbs.installDir: "lib/pkgconfig"
    }
}

When building this project, a Qbs module file mylib.qbs and a pkg-config file mylib.pc will be generated. They contain the information that is necessary to build against this library using the respective tools. The mylib.qbs file might look like this (the concrete content depends on the target platform):

Module {
    Group {
        filesAreTargets: true
        fileTags: "dynamiclibrary"
        files: "../../../libmylib.so.1.0.0"
    }
}

As you can see, the library file is specified using relative paths in order to make the installation relocatable.

Now anyone who wants to make use of the mylib library in their Qbs project can simply do so by declaring a dependency on it: Depends { name: "mylib" }.

System-level Settings

Until now, Qbs settings were always per-user. However, some settings should be shared between all users, for instance global search paths. Therefore, Qbs now supports system-level settings as well. These are considered in addition to the user-level ones, which take precedence in the case of conflicts. System-level settings can be written using the new --system option of the qbs-config tool. This operation usually requires administrator rights.

Language Improvements

We have added a new property type varList for lists of objects. You could already have those by using var properties, but the new type has proper list semantics, that is, values from different modules accumulate.

The FileInfo extension has two new functions suffix and completeSuffix.

Two changes have been done to the Rule item:

C/C++ Support

The cLanguageVersion and cxxLanguageVersion properties are now arrays. If they contain more than one value, then the one corresponding to the highest version of the respective language standard is chosen. This allows different modules to declare different minimum requirements.

Autotest Support

The AutotestRunner item has a new property auxiliaryInputs that can help ensuring that additional resources needed for autotest execution (such as helper applications) are built before the autotests run.

The working directory of an autotest is now the directory in which the respective test executable is located or AutotestRunner.workingDirectory, if it is specified. In the future, it will also be possible to set this directory per test executable.

Various things

All command descriptions now list the product name to which the generated artifact belongs. This is particularly helpful for larger projects where several products contain files of the same name, or even use the same source file.

The vcs module no longer requires a repository to create the header file. If the project is not in a repository, then the VCS_REPO_STATE macro will evaluate to a placeholder string.

It is now possible to generate Makefiles from Qbs projects. While it is unlikely that complex Qbs projects are completely representable in the Makefile format, this feature might still be helpful for debugging purposes.

Try It!

The Open Source version is available on the download page, and you can find commercially licensed packages on the Qt Account Portal. Please post issues in our bug tracker. You can also find us on IRC in #qbs on chat.freenode.net, and on the mailing list. The documentation and wiki are also good places to get started.

Qbs is also available on a number of packaging systems (Chocolatey, MacPorts, Homebrew) and updated on each release by the Qbs development team. It can also be installed through the native package management system on a number of Linux distributions including but not limited to Debian, Ubuntu, Fedora, and Arch Linux.

Qbs 1.12.0 is also included in Qt Creator 4.7.0, which was released this week as well.

The post qbs 1.12 released appeared first on Qt Blog.

How to Expose a Qt C++ Class with Signals and Slots to QML

Application Development with QML is simple and powerful. But Qt C++ can be more performant, offers many features and is less error-prone. This post shows you how to create apps that take advantage of both languages.

How to Communicate between C++ and QML

It is important to choose the right language for different features of your app. Integrate C++ components with QML to take your mobile app development to the next level.

Advantages of Coding in QML

V-Play Engine for Qt-based mobile apps and games uses the power of Qt Quick (QML + Javascript). This declarative scripting language is so powerful that it saves up to 60% lines of code compared to other programming languages.

Coding in QML has several advantages over development with C++:

  • Coding with QML + JavaScript is very easy to learn and allows to reduce the required amount of code a lot.
  • Language concepts like states, signals or property bindings are a huge time-saver.
  • QML makes adding animations simple. You can animate every property of your QML types with simple Animation components.
  • QML is extensible and flexible. For example, you can extend objects with new properties and features in-line. No need to create a new re-usable type for small extensions.
  • The QML Rendering Engine offers a great performance. The renderer uses C++ Qt and relies on a hardware accelerated scene graph. This makes it fast enough to power even high-performance games.

When to use C++ Instead

Qt app development with C++ has advantages as well. For some scenarios you need features that are only available with Qt C++. Also, C++ is fast and type-safe. This allows to provide the best possible performance for long-running and data-intense calculations.

For these examples, you would choose C++ over QML:

  • Native C++ code is the right choice for data-intense operations. It will outperform interpreted QML/JavaScript code.
  • C++ code is type-safe and compiled into object code. For parts where stability and security are important, using C++ helps to make your app less error-prone.
  • The Qt C++ components offer different and in some cases more features than the QML types. For example, advanced networking features.
  • It is also possible to mix C++ with native code for Android (over JNI) or iOS (Obj-C or Swift). This allows to provide such native functionality for QML as well.

V-Play Engine extends Qt for mobile app and game development. It already covers tasks like accessing native device features – so you don’t have to worry about going deep into C++ or Java and Obj-C.

Still, to get the most out of your application you can use the advantages of both languages. The full example of this guide is also available on GitHub:

How to Access a C++ Object from QML

Before we go into any details, let us start by creating a simple V-Play Apps project with Qt Creator. If you are new to V-Play and don’t know how, please consider having a look at the Getting Started Tutorial or the V-Play Designer Tutorial Video.

To sign-up and install V-Play, see the download page of the V-Play website.

Note: Adding custom C++ code is not supported when testing with QML Live. Please build your project with the classic RUN button to test the examples below.

Create a C++ Class in your V-Play Project

1. After creating a new app project, first replace the code in Main.qml with this basic structure:

import VPlayApps 1.0
import QtQuick 2.5

App {

 NavigationStack {
   Page {
     title: "Integrate C++ and QML"
   }
 }
}

It only includes the main App window and a Page within NavigationStack to show a navigation bar that holds the page title:

V-Play App with a Page

2. This is enough for our basic QML setup. Let’s go on by creating a new C++ class. First, right-click the C++ “Sources” folder of your project in Qt Creator, select “Add New…” and choose the “C++ Class” template in the C++ section:

Add a new C++ Class

3. Then set “MyGlobalObject” as Class Name and select “Include QObject” to include the QObject type, as the main requirement to prepare our class for usage with QML is to derive from QObject.

Derive C++ class from QObject

After completing the wizard, your project contains the class definition myglobalobject.h in the “Headers” folder and the implementation myglobalobject.cpp in the “Sources” folder of the project.

Qt Creator C++ type header and source files

Note that the *.pro configuration now also includes the new files in the HEADERS and SOURCES configuration.

Implement the C++ Class with Signals and Slots for Usage with QML

1. Open myglobalobject.h and add some code to derive from QObject – the required include statement is already in place:

#ifndef MYGLOBALOBJECT_H
#define MYGLOBALOBJECT_H

#include <QObject>

class MyGlobalObject : public QObject
{
 Q_OBJECT

public:
 MyGlobalObject();
};

#endif // MYGLOBALOBJECT_H

Do not forget to also add the Q_OBJECT preprocessor macro within the class definition.

2. Now that we have a new QObject, let’s add a simple method we will later call from QML. To make the method available in QML, it is required to mark it as a public slot:

class MyGlobalObject : public QObject
{
 Q_OBJECT

public:
 MyGlobalObject();

public slots: // slots are public methods available in QML
 void doSomething(const QString &text);
};

3. To complete our basic class, open myglobalobject.cpp and add the method implementation for doSomething(). We keep it simple and only print the given text to the debug output.

#include "myglobalobject.h"
#include <QDebug>

MyGlobalObject::MyGlobalObject()
{
 // perform custom initialization steps here
}

void MyGlobalObject::doSomething(const QString &text) {
 qDebug() << "MyGlobalObject doSomething called with" << text;
}

Expose an Object to QML as a Context Property

One possible way to work with a C++ object in QML is to add the object as a property to the root context of the QML tree. You can decide on a name for the property, which is then globally available in your QML code.

1. To create a new object of our class and add it as a property, we extend the main.cpp code:

// keep existing includes here
// include qml context, required to add a context property
#include <QQmlContext>

// include custom class
#include "myglobalobject.h"

int main(int argc, char *argv[])
{
 // V-Play initialization ...

 // add global c++ object to the QML context as a property
 MyGlobalObject* myGlobal = new MyGlobalObject();
 myGlobal->doSomething("TEXT FROM C++");
 engine.rootContext()->setContextProperty("myGlobalObject", myGlobal); // the object will be available in QML with name "myGlobalObject"

 engine.load(QUrl(vplay.mainQmlFileName()));
 return app.exec();
}

Note: It is possible to fully use the object also in C++. The above code example already includes a test-call to our doSomething method.

2. In the Main.qml of our project, we extend our Page with a Column and a first AppButton, which calls the doSomething() method when clicked:

   Page {
     title: "Integrate C++ and QML"

     // Example 1 - Global Context Property
     // NOTE: myGlobalObject is available here because it is set as a context property in main.cpp
     Column {

       // 1.1: Calling myGlobalObject.doSomething() function
       AppButton {
         text: "myGlobalObject.doSomething()"
         onClicked: myGlobalObject.doSomething("TEXT FROM QML")
       }

     }
   }

Button to call the c++ function

3. Let’s hit the green run button in Qt Creator to see how it works. The debug output shows the initial method call from main.cpp and with a click on the button another message appears:
MyGlobalObject doSomething called with “TEXT FROM QML”

Qt Creator C++ function log from QML

That’s all we need to call methods of a C++ Object from QML. This already allows simple communication from QML to C++, but there’s even more we can do. QML supports many amazing concepts like value-changed listeners of properties and property bindings, which make development a lot easier. So let’s add a full-featured QML property to our C++ class!

Add a Class Property with Full QML Support

1. Open mylgobalobject.h and add a private counter property with a public getter and setter method.

class MyGlobalObject : public QObject
{
// …


public:
 int counter() const;
 void setCounter(int value);

private:
 int m_counter;
};

2. Implement the required methods and initialize the counter property in myglobalobject.cpp

MyGlobalObject::MyGlobalObject() : m_counter(0)
{
 // perform custom initialization steps here
}

int MyGlobalObject::counter() const {
 return m_counter;
}

void MyGlobalObject::setCounter(int value) {
 if(m_counter != value) {
   m_counter = value;
 }
}

3. Similar to other properties in QML, we also want to be able to dynamically react to property changes in our QML code. In other words, we want to trigger functions in QML when the C++ property changes. Unlike the slots, which make C++ methods callable in QML, signals can be used to trigger QML code from C++. So the data flow looks like this:

C++ and QML data flow with signals and slots

Let’s add a signal counterChanged and trigger it in our setCounter implementation:

myglobalobject.h:

class MyGlobalObject : public QObject
{
//  ...

signals:
 void counterChanged();
};

myglobalobject.cpp:

void MyGlobalObject::setCounter(int value) {
 if(m_counter != value) {
   m_counter = value;
   counterChanged(); // trigger signal of counter change
 }
}

4. This simple change already allows us to add handler functions for the counterChanged() signal in QML. However, our counter property is still a normal C++ property with a getter and setter method. We can take care of that with an additional preprocessor macro:

class MyGlobalObject : public QObject
{
 Q_OBJECT
 Q_PROPERTY(int counter READ counter WRITE setCounter NOTIFY counterChanged) // this makes counter available as a QML property

// ...
};

The Q_PROPERTY macro defines a property counter and configures the methods for reading and writing the property, as well as the signal that notifies property changes. This configuration is used by QML to work with the property.

5. Let’s extend our Main.qml and use our new counter property. The following snippet adds a new button to increase the counter and a text item to display the value:

     Column {

       // ...

       // 1.2: Increasing myGlobalObject.counter property
       // NOTE: the defined setter function of the property is used automatically and triggers the counterChanged signal
       AppButton {
         text: "myGlobalObject.counter + 1"
         onClicked: {
           myGlobalObject.counter = myGlobalObject.counter + 1
         }
       }

       // 1.3: Showing myGlobalObject counter value in a QML text
       // NOTE: property bindings are supported, as the counter property definition includes the counterChanged signal, which is fired in the implementation of MyGlobalObject::setCounter() for each property change
       AppText {
         text: "Global Context Property Counter: " + myGlobalObject.counter
       }
     } // Example 1

Our property is usable like any other property in QML. Thanks to the counterChanged we prepared, the text even updates automatically every time we change the counter.

This is how the final example looks like:

Access C++ class property from QML

How to Register your C++ Class as a QML Type

The second possibility to use C++ components in QML is to register the class as a QML type. This allows to create objects (= instances) of your type directly in QML instead of C++. And the best thing is, the concepts with signals, slots and properties we used in the previous example still apply.

When to Use a Context Property and when a QML Object

If there’s only a single object instance you want to work with in QML you can add the object as a context property. When there can be multiple instances of your class, register it as a QML type and create the objects directly in QML where you need it.

1. For this example, we will create a new type we can use in QML. Let’s start with adding a new C++ Class named MyQMLType

Create a QML type with C++

2. Replace the code in myqmltype.h with this implementation:

#ifndef MYQMLTYPE_H
#define MYQMLTYPE_H

#include <QObject>

class MyQMLType : public QObject
{
 Q_OBJECT
 Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged) // this makes message available as a QML property

public:
 MyQMLType();

public slots: // slots are public methods available in QML
 int increment(int value);

signals:
 void messageChanged();

public:
 QString message() const;
 void setMessage(const QString& value);

private:
 QString m_message;

};

#endif // MYQMLTYPE_H

Similar to the previous example, this type will have one public slot and a full-featured property with a getter method, a setter method and a property changed signal. The increment method increases a given integer value by one and the message property will store a string value.

3. To complete the class, add the following code for myqmltype.cpp:

#include "myqmltype.h"

MyQMLType::MyQMLType() : m_message("")
{

}

int MyQMLType::increment(int value) {
 return value + 1;
}

QString MyQMLType::message() const {
 return m_message;
}

void MyQMLType::setMessage(const QString& value) {
 if(m_message != value) {
   m_message = value;
   messageChanged(); // trigger signal of property change
 }
}

Which Parameters Can you Pass between C++ and QML

In contrast to the previous example, our new class also uses a return value for the increment slot. No further adjustments are required to receive the return value in QML. Qt automatically maps basic C++ types to QML types for all method parameters and return values.

For more information about available Qt types and corresponding QML types, please see Data Type Conversion Between QML and C++.

Register and Use your C++ QML Type

1. In your main.cpp, first add an include statement for the new class:

#include "myqmltype.h"

2. Then use qmlRegisterType to add the class as a QML Type.

int main(int argc, char *argv[])
{
 // ...

 // register a QML type made with C++
 qmlRegisterType<MyQMLType>("com.yourcompany.xyz", 1, 0, "MyQMLType"); // MyQMLType will be usable with: import com.yourcompany.xyz 1.0

 engine.load(QUrl(vplay.mainQmlFileName()));
 return app.exec();
}

The method takes several parameters: The module identifier and version define the required QML import to use the type. The last parameter holds the name of the QML type, which can be different from the actual C++ class name.

3. Add the import which matches the used configuration of qmlRegisterType to your Main.qml:

// NOTE: the import identifier, version and QML type name are set in main.cpp at qmlRegisterType(...)
import com.yourcompany.xyz 1.0

4. For an example usage of our new QML Type, add the following snippet below the first example:

   Page {
     title: "Integrate C++ and QML"
 
     Column {
       // ...      

     // Example 2: Custom QML Type implemented with C++
     // NOTE: This type is declared in main.cpp and available after using "import com.yourcompany.xyz 1.0"
     MyQMLType {
       id: typeFromCpp

       // 2.1: Property Binding for MyQMLType::message property
       // NOTE: Similar to types created purely with QML, you may use property bindings to keep your property values updated
       message: "counter / 2 = " + Math.floor(myGlobalObject.counter / 2)

       // 2.2: Reacting to property changes
       // NOTE: With the onMessageChanged signal, you can add code to handle property changes
       onMessageChanged: console.log("typeFromCpp message changed to '" + typeFromCpp.message+"'")

       // 2.3: Run code at creation of the QML component
       // NOTE: The Component.onCompleted signal is available for every QML item, even for items defined with C++.
       // The signal is fired when the QML Engine creates the item at runtime.
       Component.onCompleted: myGlobalObject.counter = typeFromCpp.increment(myGlobalObject.counter)
     }

     // 2.1: Show typeFromCpp.message value, which is calculated automatically based on the myGlobalObject.counter value
     AppText {
       text: "Custom QML Type Message:\n" + typeFromCpp.message
     }
   }

The code shows that we can now use MyQMLType like any other QML item. The message property is initialized inline with a property binding, that shows the integer result of dividing myGlobalObject.counter by two. Whenever the counter changes, this expression is re-evaluated automatically.

In addition, when in turn the message changes (every 2 counter steps), we use the onMessageChanged signal to display the new message in the log output.

Similar to other QML Items, the Component.onCompleted signal is available to perform initialization steps when the QML engine creates the object. In this example, we use the increment slot to increase the counter by 1.

The AppText at the bottom simply displays the message property:

cpp-qml-2-2-use-qml-type-created-with-cpp

 

Use a Property, Signal or Slot?

As we’ve already seen in the previous examples, properties, signals and slots offer different types of communication between C++ and QML:

  • Slots allow communication from QML to C++: Slots are used to trigger C++ code from QML. You can use parameters and return values to pass data to and from C++.
  • Signals allow communication from C++ to QML: Signals are used to run QML code when certain events occur C++. You can pass parameters from C++ to QML. However, you can not return data from QML.
    In contrast to slots, signals may be handled by none, one or many components. There is no guarantee that triggering a signal in C++ will actually run QML code, unless there’s a handler defined.

Properties work both ways: Properties are read- and write-able from both C++ and QML. To support property bindings in QML, make sure to add a changed-signal for the property and do not forget to trigger the signal in C++ whenever the value changes.

C++ and QML data flow with properties, signals or slots

How to Start Long-running C++ Operations from QML

The above example already fully covers slots and properties, but only uses a signal as part of the property configuration. To complete the example, let’s add a new slot startCppTask(), a new method doCppTask() and a new signal cppTaskFinished() to myqmltype.h:

public slots: 
 int increment(int value);
 void startCppTask(); // starts internal calculations of doCppTask()

signals:
 void messageChanged();
 void cppTaskFinished(); // triggered after calculations in doCppTask()

public:
 QString message() const;
 void setMessage(const QString& value);

private:
 void doCppTask(); // method for internal calculations
 QString m_message;

We will later call the slot startCppTask() from QML, which executes the internal doCppTask() method. You can e.g. run calculations in another thread at this point to avoid blocking the QML UI while performing the task. This is useful for any cpu-intense or long-lasting operation you want to handle in C++. By adding the implementation for the methods to myqmltype.cpp, we are fnished with the C++ part.

void MyQMLType::startCppTask() {
 this->doCppTask();
}

void MyQMLType::doCppTask() {
 // NOTE: you can do calculations here in another thread, this may be used to perform
 // cpu-intense operations for e.g. AI (artificial itelligence), Machine Learning or similar purposes
 // When the work is done, we can trigger the cppTaskFinished signal and react anyhwhere in C++ or QML
 cppTaskFinished();
}

As everything is prepared now, we can add another AppButton that starts our C++ task:

// 2.4: Button to start cpp task
AppButton {
  text: "typeFromCpp.startCppTask()"
  onClicked: {
      typeFromCpp.startCppTask()
  }
}

The onCppTaskFinished() signal will notify us when the C++ part has finished calculations:

MyQMLType {
  // ...

  // 2.4: Handling a custom signal
  onCppTaskFinished: {
    myGlobalObject.counter = 0 // reset counter to zero, this will also update the message
  }
}

In this example, we simply reset our global counter to zero when the signal fires, which will also update the message property of MyQMLType.

This is how the final example looks like after executing the cpp task:

Run asynchronous C++ task with QML

Note: To handle custom signals in QML when using a context property, use the Connections QML Type. The following snippet adds a handler to the counterChanged() signal of myGlobalObject:

// 2.5: Connections allow to add signal handlers for global context property objects
Connections {
    target: myGlobalObject
    onCounterChanged: console.log("Counter changed to " + myGlobalObject.counter)
}

When to Derive from QQuickItem instead of QObject

In all used examples, we created a C++ Class which extends QObject. However there are some limitations to QObjects: QObjects do not have a visual representation. This means, they can not hold any child items and properties regarding visual features like size, position, visibility are not available.

A QObject only holds data and logic you can use in QML as properties, signals and slots. When registering a QObject class as a type for QML, keep this restriction in mind. To create a QML Item with C++ which should support a visual representation with all default properties, derive from QQuickItem instead.

As this short introduction does not cover implementing QQuickItems, please see the the Qt documentation for more information. The overview page about Integrating QML and C++ is found here.

The full source code of the project created in this guide can be found on GitHub:

 

 

More Posts Like This

 

Add Chat Service and Cross-Platform Leaderboard with User Profiles to Your iOS or Android App
Add Chat Service and Cross-Platform Leaderboard with User Profiles to Your iOS or Android App

Release 2.14.1: Update to Qt 5.9.3 | Use Live Code Reloading on macOS and Linux
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

The post How to Expose a Qt C++ Class with Signals and Slots to QML appeared first on V-Play Engine.

Qt Creator 4.7.0 released

We are happy to announce the release of Qt Creator 4.7.0!

C++ Support

We decided that it is time to turn the Clang code model on by default. It made huge progress during the last releases, and at some point we need to do this switch. The built-in model cannot keep up with the developments in the C++ language, nor with the development of the available tooling around it. We nowadays regularly close bug reports with the comment “works with Clang code model”. Also, the Clang code model provides much better information about issues in code without going through the edit-compile-analyze cycle explicitly. Please also have a look at Nikolai’s blog post on the Clang code model and the history of C/C++ support in Qt Creator.

There can be situations where the built-in model still works better for you than the Clang code model, and you continue to have the option to use it instead, by disabling the ClangCodeModel plugin. The global symbol index is also still created with the built-in model.

Project wide diagnostics and fixits in Qt Creator by clang-tidy and clazy

We upgraded the Clang code model to Clang 6.0. It now provides the information for the overview of the current document, which is used for the symbols dropdown, outline pane and “.” locator filter. You also have more freedom in deciding which Clang-Tidy and Clazy checks you want to run while editing, and have the option to run checks over your whole code base through a new tool in Debug mode (Analyze > Clang-Tidy and Clazy). The warnings and errors from the code model are now also optionally shown in the Issues pane.

Test Integration

If your text cursor in the C++ editor is currently inside a test function, you can directly run that individual test with the new Run Test Under Cursor action. The test integration now also marks the location of failed tests in the editor. For Google Test we added support for filtering.

Windows Hosts

On Windows we improved the scanning for MSVC compilers, which previously could block Qt Creator. We also fixed an issue which could lead to short term freezes while Qt Creator was listening to the global, shared Windows debug stream. And saving files on network drives should work again in all configurations.

Other Improvements

The kit options are one of the most important settings that you might need to adapt for your projects in Qt Creator. So we put them in their own top-level entry in the preferences dialog, which is also the very first one in the list.

If you have a HiDPI screen on Windows or Linux, you can now easily choose if you want Qt’s automatic scaling or not, by enabling or disabling the new option in Environment > Interface.

The File System view got new options for showing folders on top as opposed to integrated into the alphabetic sorting, and for turning off the synchronization of the base folder with the current document’s project. You can also create new folders directly in the File System view now.

There have been many more improvements and fixes. Please refer to our changes file for a more comprehensive list.

Get Qt Creator 4.7.0

The opensource version is available on the Qt download page, and you find commercially licensed packages on the Qt Account Portal. Qt Creator 4.7.0 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.7.0 released appeared first on Qt Blog.

Release 2.17.1: Use Qt 3D with Live Reloading and Test Plugin Code Examples from Browser

V-Play 2.17.1 adds a long list of improvements and fixes. You can now also use 3D components with live code reloading in your apps and games. The plugin documentation now includes the example run button. Use it to test code examples for ads, Firebase and more from the browser on your mobile device. You can also learn how to make custom list delegates with 2 new examples in the documentation.

Use Qt 3D in Your Apps and Games, with Live Code Reloading

V-Play and Qt make it easy to add 3D content to your apps or 2D games. With the QML 3D modules, you can embed 3D objects anywhere within your app. This feature is now also available with the Live Clients on desktop, iOS and Android.

Here is a small code example for you to try right away. It displays a 3D cube on your page. The cube rotates depending on the device rotation, using the RotationSensor. You can also change the color of the cube. All that with about 130 lines of code, without empty lines and comments it’s about 100 lines.

v-play-3d-cube-rotation-sensor-color-select

import VPlayApps 1.0
import QtQuick 2.9
// 3d imports
import QtQuick.Scene3D 2.0
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
import QtSensors 5.9

App {
  // Set screen to portrait in live client app (not needed for normal deployment)
  onInitTheme: nativeUtils.preferredScreenOrientation = NativeUtils.ScreenOrientationPortrait
          
  RotationSensor {
    id: sensor
    active: true
    // We copy reading to custom property to use behavior on it
    property real readingX: reading ? reading.x : 0
    property real readingY: reading ? reading.y : 0
    // We animate property changes for smoother movement of the cube
    Behavior on readingX {NumberAnimation{duration: 200}}
    Behavior on readingY {NumberAnimation{duration: 200}}
  }
  
  NavigationStack {
    Page {
      title: "3D Cube on Page"
      backgroundColor: Theme.secondaryBackgroundColor
      
      Column {
        padding: dp(15)
        spacing: dp(5)
        
        AppText {
          text: "x-axis " + sensor.readingX.toFixed(2)
        }
        AppText {
          text: "y-axis " + sensor.readingY.toFixed(2)
        }
      }
      
      // 3d object on top of camera
      Scene3D {
        id: scene3d
        anchors.fill: parent
        focus: true
        aspects: ["input", "logic"]
        cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
        
        Entity {
          
          // The camera for the 3d world, to view our cube
          Camera {
            id: camera3D
            projectionType: CameraLens.PerspectiveProjection
            fieldOfView: 45
            nearPlane : 0.1
            farPlane : 1000.0
            position: Qt.vector3d( 0.0, 0.0, 40.0 )
            upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
            viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
          }
          
          components: [
            RenderSettings {
              activeFrameGraph: ForwardRenderer {
                camera: camera3D
                clearColor: "transparent"
              }
            },
            InputSettings { }
          ]
          
          PhongMaterial {
            id: material
            ambient: Theme.tintColor // Also available are diffuse, specular + shininess to control lighting behavior
          }
          
          // The 3d mesh for the cube
          CuboidMesh {
            id: cubeMesh
            xExtent: 8
            yExtent: 8
            zExtent: 8
          }
          
          // Transform (rotate) the cube depending on sensor reading
          Transform {
            id: cubeTransform
            // Create the rotation quaternion from the sensor reading
            rotation: fromAxesAndAngles(Qt.vector3d(1,0,0), sensor.readingX*2, Qt.vector3d(0,1,0), sensor.readingY*2)
          }
          
          // The actual 3d cube that consists of a mesh, a material and a transform component
          Entity {
            id: cubeEntity
            components: [ cubeMesh, material, cubeTransform ]
          }
        }
      } // Scene3D
      
      // Color selection row
      Row {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        spacing: dp(5)
        padding: dp(15)
        
        Repeater {
          model: [Theme.tintColor, "red", "green", "#FFFF9500"]

          Rectangle {
            color: modelData
            width: dp(48)
            height: dp(48)
            radius: dp(5)
            
            MouseArea {
              anchors.fill: parent
              onClicked: {
                material.ambient = modelData
              }
            }
          }
        }
      }
    } // Page
  } // NavigationStack
} // App

Test Code Examples from Plugin Documentation

You can now test the code examples from the plugin documentation. This allows you to run code examples from the documentation on your mobile phone. Just like you are used to from the apps documentation, you can now also test plugins for ads, firebase, analytics and more right from your browser.

You can currently test code examples of the following plugins from the documentation:

 

Here’s a little example for an AdMob advertisement banner:

v-play-admob-banner-ios-live-client

import VPlayApps 1.0
import VPlayPlugins 1.0

App {
  NavigationStack {
    Page {
      title: "Admob Banner"
      
      AdMobBanner {
        adUnitId: "ca-app-pub-3940256099942544/6300978111" // banner test ad by AdMob
        banner: AdMobBanner.Smart
      }
    }
  }
}

New Examples for Custom App List View Delegates

Many of you requested this, so this update adds 2 new examples to the ScollView and ListView documentation. You can check out how to create custom delegate components and display your data with the modelData property.

The second example shows custom foldable delegate components.

applistview-subsections

Improved Handling of Screen Keyboard on iOS and Android

App and GameWindow provide new properties to make the native keyboard handling on Android and iOS easier. You can use keyboardVisible and keyboardHeight to adapt your app layout when the keyboard is shown.

The following example displays a floating action button above the keyboard. It also adapts to size changes of the keyboard:

keyboard-height-floating-action-button


import VPlayApps 1.0
import QtQuick 2.7

App {
  id: app
  
  // We unset the focus from the AppTextField after the keyboard was dismissed from the screen
  onKeyboardVisibleChanged: if(!keyboardVisible) textField.focus = false
  
  NavigationStack {
    
    Page {
      id: page
      title: qsTr("Keyboard Height")
      
      AppTextField {
        id: textField
        width: parent.width
        font.pixelSize: sp(25)
      }
      
      FloatingActionButton {
        // Add the keyboard height as bottom margin, so the button floats above the keyboard
        anchors.bottomMargin: app.keyboardHeight + dp(15)
        // We only show the button if the AppTextField has focus and the keyboard is expanded
        visible: textField.focus && app.keyboardHeight != 0
        icon: IconType.check
        backgroundColor: Theme.tintColor
        iconColor: "white"
        onClicked: textField.focus = false
      }
    }
  }
}

More Features, Improvements and Fixes

Here is a compressed list of improvements with this update:

For a list of additional fixes, please check out the changelog.

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 this release 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 this release!

For a full list of improvements and fixes to V-Play in this update, please check out the change log!

 

 

 

More Posts Like This

 

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

vplay-2-17-0-firebase-cloud-storage-downloadable-resources-and-more

Release 2.17.0: Firebase Cloud Storage, Downloadable Resources at Runtime and Native File Access on All Platforms

vplay-update-2.16.1-live-client-module-live-code-reloading-custom-cpp

Release 2.16.1: Live Code Reloading with Custom C++ and Native Code for Qt

teaser-iphonex-support-and-runtime-screen-orientation-change-705px

Release 2.16.0: iPhone X Support and Runtime Screen Orientation Changes

The post Release 2.17.1: Use Qt 3D with Live Reloading and Test Plugin Code Examples from Browser appeared first on V-Play Engine.

Cutelyst 2.5.0 released

Cutelyst a C++ web framework based on Qt got a new release. This release has some important bug fixes so it's really recommended to upgrade to it.

Most of this release fixes came form a side project I started called Cloudlyst, I did some work for the NextCloud client, and due that I became interested into how WebDAV protocol works, so Cloudlyst is a server implementation of WebDAV, it also passes all litmus tests. WebDAV protocol makes heavy use of REST concept, and although it uses XML instead of JSON it's actually a good choice since XML can be parsed progressively which is important for large directories.

Since the path URL now has to deal with file paths it's very important it can deal well with especial characters, and sadly it did not, I had tried to optimize percent encoding decoding using a single QString instead of going back and forth toLatin1() then fromUTF8() and this wasn't working at all, in order to better fix this the URL is parsed a single time at once so the QString path() is fully decoded now, which will be a little faster and avoid allocations. And this is now unit tested :)

Besides that there was:

  • Fix for regression of auto-reloading apps in cutelyst-wsgi
  • Fix csrf token for multipart/form-data (Sebastian Held)
  • Allow compiling WSGI module when Qt was not built with SSL support

The last one and another commit were to fix some build issues I had with buildroot, which I also created a package so soon you will be able to select Cutelyst from buildroot menu.

Have fun https://github.com/cutelyst/cutelyst/releases/tag/v2.5.0

Qt for Python available at PyPi

We are glad to announce that finally the technical preview of Qt for Python is available at the Python Package Index (PyPI).

For the past technical preview release, we were still discussing with the PyPi people to be able to upload our wheels to their servers, but now everything is in order, and you can get the PySide2 module with a simple:


pip install PySide2

Keep in mind that we will continue uploading the snapshot wheels to our servers,
so you also can get the latest features of Qt for Python!.

The post Qt for Python available at PyPi appeared first on Qt Blog.

New client languages for Qt WebChannel

At the company I’m working at, we’re employing Qt WebChannel for remote access to some of our software. Qt WebChannel was originally designed for interfacing with JavaScript clients, but it’s actually very well suited to interface with any kind of dynamic language.

We’ve created client libraries for a few important languages with as few dependencies as possible: pywebchannel (Python, no dependencies), webchannel.net (.NET/C#, depends on JSON.NET) and webchannel++ (header-only C++14, depends on Niels Lohmann’s JSON library).

Python and .NET are a pretty good match: Their dynamic language features make it possible to use remote methods and properties like they were native. Due to being completely statically typed, C++ makes the interface a little more clunky, although variadic templates help a lot to make it easier to use.

As with the original Qt WebChannel C++ classes, transports are completely user defined. When sensible, a default implementation of a transport is provided.

Long story short, here’s an example of how to use the Python client. It’s designed to talk with the chatserver example of the Qt WebChannel module over a WebSocket. It even supports the asyncio features of Python 3! Relevant excerpt without some of the boilerplate:

async def run(webchannel):
    # Wait for initialized
    await webchannel
    print("Connected.")

    chatserver = webchannel.objects["chatserver"]

    username = None

    async def login():
        nonlocal username
        username = input("Enter your name: ")
        return await chatserver.login(username)

    # Loop until we get a valid username
    while not await login():
        print("Username already taken. Please enter a new one.")

    # Keep the username alive
    chatserver.keepAlive.connect(lambda *args: chatserver.keepAliveResponse(username))

    # Connect to chat signals
    chatserver.newMessage.connect(print_newmessage)
    chatserver.userListChanged.connect(lambda *args: print_newusers(chatserver))

    # Read and send input
    while True:
        msg = await ainput()
        chatserver.sendMessage(username, msg)


print("Connecting...")
loop = asyncio.get_event_loop()
proto = loop.run_until_complete(websockets.client.connect(CHATSERVER_URL, create_protocol=QWebChannelWebSocketProtocol))
loop.run_until_complete(run(proto.webchannel))

pywebchannel can also be used without the async/await syntax and should also be compatible with Python 2.

I would also really like to push the code upstream, but I don’t know when I’ll have the time to spare. Then there’s also the question of how to build and deploy the libraries. Would the qtwebchannel module install to $PYTHONPREFIX? Would it depend on a C# compiler (for which support would have to be added to qmake)?

In any case, I think the client libraries can come in handy and expand the spectrum of application of Qt WebChannel.

Profiling memory usage on Linux with Qt Creator 4.7

The Performance Analyzer

You may have heard about the Performance Analyzer (called “CPU Usage Analyzer” in Qt Creator 4.6 and earlier). It is all about profiling applications using the excellent “perf” tool on Linux. You can use it locally on a Linux-based desktop system or on various embedded devices. perf can record a variety of events that may occur in your application. Among these are cache misses, memory loads, context switches, or the most common one, CPU cycles, which periodically records a stack sample after a number of CPU cycles have passed. The resulting profile shows you what functions in your application take the most CPU cycles. This is the Performance Analyzer’s most prominent use case, at least so far.

Creating trace points

With Qt Creator 4.7 you can also record events for trace points, and if your trace points follow a certain naming convention Qt Creator will know they signify resource allocations or releases. Therefore, by setting trace points on malloc, free, and friends you can trace your application’s heap usage. To help you set up trace points for this use case, Qt Creator packages a shell script you can execute and prompts you to run it. First, open your project and choose the run configuration you want to examine. Then just select the “Create trace points …” button on the Analyzer title bar and you get:

Memory Profiling: Creating trace points

How does it work?

In order for non-privileged users to be able to use the trace points the script has to make the kernel debug and tracing file systems available to all users of the system. You should only do this in controlled environments. The script will generally work for 32bit ARM and 64bit x86 systems. 64bit ARM systems can only accept the trace points if you are using a Linux kernel of version 4.10 or greater. In order to set trace points on 32bit x86 systems you need to have debug symbols for your standard C library available

The script will try to create trace points for any binary called libc.so.6 it finds in /lib. If you have a 64-bit system with additional 32-bit libraries installed, it will try to create trace points for both sub-architectures. It may only succeed for one of them. This is not a problem if your application targets the sub-architecture for which the script succeeded in setting the trace points.

Troubleshooting

If the trace point script fails, you may want to check that your kernel was compiled with the CONFIG_UPROBE_EVENT option enabled. Without this option the kernel does not support user trace points at all. All 32-bit ARM images shipped with Qt for Device Creation have this option enabled from version 5.11 on. Most Linux distributions intended for desktop use enable CONFIG_UPROBE_EVENT by default.

Using trace points for profiling

After creating the trace points, you need to tell Qt Creator to use them for profiling. There is a convenient shortcut for this in the Performance Analyzer Settings. You can access the settings either for your specific project in the “Run” settings in “Projects” mode, or globally from the “Options” in the “Tools” menu. Just select”Use Trace Points”. Then Qt Creator will replace your current event setup with any trace points it finds on the target system, and make sure to record a sample each time a trace point is hit.

Memory Profiling: Adding trace events to Qt Creator

After this, you only need to press the “Start” button in the profiler tool bar to profile your application. After the application terminates, Qt Creator collects the profile data and displays it.

Interpreting the data

The easiest way to figure out which pieces of code are wasting a lot of memory is by looking at the flame graph view. In order to get the most meaningful results, choose the “Peak Usage” mode in the top right. This will show you a flame graph sorted by the accumulated amount of memory allocated by the given call chains. Consider this example:

Memory Profiling: Flame Graph of peak usage

Findings

What you see here is a profile of Qt Creator loading a large QML trace into the QML Profiler. The QML profiler uses a lot of memory when showing large traces. This profile tells us some details about the usage. Among other things this flame graph tells us that:

  • The models for Timeline, Statistics, and Flame Graph views consume about 43% of the peak memory usage. TimelineTraceManager::appendEvent(…) dispatches the events to the various models and causes the allocations.
  • Of these, the largest part, 18.9% is for the Timeline range models. The JavaScript, Bindings, and Signal Handling categories are range models. They keep a vector of extra data, with an entry for each such range. You can see the QArrayData::allocate(…) that allocates memory for these vectors.
  • Rendering the Timeline consumes most of the memory not allocated for the basic models. In particular Timeline::NodeUpdater::run() shows up in all of the other stack traces. This function is responsible for populating the geometry used for rendering the timeline categories. Therefore, QSGGeometry::allocate(…) is what we see as direct cause for the allocations. This also tells us why the QML profiler needs a graphics card with multiple gigabytes of memory to display such traces.

Possible Optimizations

From here, it’s easy to come up with ideas for optimizing the offending functions. We might reconsider if we actually need all the data stored in the various models, or we might temporarily save it to disk while we don’t need it. The overwhelming amount of geometry allocated here also tells us that the threshold for coalescing adjacent events in dense trace might be too low. Finally, we might be able to release the geometry in main memory once we have uploaded it to the GPU.

Tracing Overhead

Profiling each and every malloc() and free() call in your application will result in considerable overhead. The kernel will most likely not be able to keep up and will therefore drop some of the samples. Depending on your specific workload the resulting profile can still give you relevant insights, though. In other words: If your application allocates a huge amount of memory in only a handful of calls to malloc(), while also allocating and releasing small amounts at a high frequency, you might miss the malloc() calls you are interested in because the kernel might drop them. However,  if the problematic malloc() calls form a larger percentage of the total number of calls, you are likely to catch at least some of them.

In any case, Qt Creator will present you with absolute numbers for allocations, releases, and peak memory usage. These numbers refer to the samples perf actually reported, and therefore are not totally accurate. Other tools will report different numbers.

Special allocation functions

Furthermore, there are memory allocation functions you cannot use for profiling this way. In particular posix_memalign() does not return the resulting pointer on the stack or in a register. Therefore, we cannot record it with a trace point. Also, custom memory allocators you may use for your application are not handled by the default trace points. For example, the JavaScript heap allocator used by QML will not show up in the profile. For this particular case you can use the QML Profiler, though. Also, there are various drop-in replacements for the standard C allocation functions, for example jemalloc or tcmalloc. If you want to track these, you need to define custom trace points.

Conclusion

Profiling memory usage with Qt Creator’s Performance Analyzer is an easy and fast way to gain important insights about your application’s memory usage. It works out of the box for any Linux targets supported by Qt Creator. You can immediately browse the resulting profile data in an easily accessible GUI, without any further processing or data transfer. Other tools can produce more accurate data. However, for a quick overview of your application’s memory usage the Performance Analyzer is often the best tool.

The post Profiling memory usage on Linux with Qt Creator 4.7 appeared first on Qt Blog.

Qt Creator 4.7 RC released

We are happy to announce the release of Qt Creator 4.7 RC!

After 2 weeks and 70 changes since the Beta2, we think that we are almost ready for the final release of Qt Creator 4.7. So this is a good time to give us some last feedback, best done through our bug tracker.

Get Qt Creator 4.7 RC

The opensource version is available on the Qt download page, and you find commercially licensed packages on the Qt Account Portal. Qt Creator 4.7 RC is also available under Preview > Qt Creator 4.7.0-rc1 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.7 RC released appeared first on Qt Blog.

KDAB at Meet Qt in Paris

Thanks for joining us for this year’s edition of Meet Qt that took place in Paris on the 19th June.

The focus this year was medical and automotive and the event was again very successful despite the train strikes. If you could not attend here is an idea of what KDAB offered:

A medical client’s showcase presentation – Qi Tissue using Qt 3D and taking the hunt for a cure for cancer to new levels.

Learn more about this project and watch the video

Download the presentation slides…

For automotive needs, Qt Automotive Suite attached to GammaRay directly via Qt Creator provides a comprehensive package, including the powerful Qt 3D framework.

Watch the video…

Qt Quick Software Renderer provides a fluid 60fps touch UI and H.264 video decoding on hardware with no GPU or hardware video decoding acceleration, with the full feature set of Qt and with as little as 64MB of RAM and/or Flash memory.

Find out more and see the video…

The post KDAB at Meet Qt in Paris appeared first on KDAB.

KDAB at Italian C++, Milan

KDAB was sponsor of this annual C++ event run by the C++ Community for the C++ Community in Italy, which was founded some five years ago and is growing fast.

our-roll-upAround 200 people showed up for “++ it”, 50 more than last year, and were treated to an excellent program.

There was a mix of talks in either English or Italian, including ‘Debug C++ Without Running‘ by Anastasia Kazakova, ‘C++ Barbarian Quiz & Introduction to Conan C/C++ Package Manager‘ from Diego Rodriguez-Losada Gonzalez and one from Vittorio Romeo on ‘Zero-allocation & no type erasure futures‘, all of which KDAB particularly enjoyed.

You can see the full program and a post-event report here.

 

 

The post KDAB at Italian C++, Milan appeared first on KDAB.

What’s in a Qt 3D Studio Scene?

Now that Qt 3D Studio 2.0 has been released, let’s look at what some of the new features enable. In particular, we will visit the so-called in-scene debug and profile views, as these handy, built-in (both to the viewer launched from the editor and, if the developer decides so, to applications) views allow answering questions like What happens between loading a scene and issuing OpenGL draw commands?, Is this 3D scene too heavy?, How much graphics resources does this scene use?, or Is there any chance this scene will perform on this or that embedded hardware?

Note that this post assumes a certain level of familiarity with the basic concepts of Qt 3D Studio. For an introduction, refer to the editor and runtime Getting Started pages of the documentation.

profui11

Firing up the viewer by clicking the green Play button in the toolbar of the Qt 3D Studio application launches q3dsviewer, which is a simple Qt application that uses the Qt 3D Studio Runtime to load and render the presentation into a QWindow. With 2.0 and its migration to a new engine that is using Qt 3D internally, the viewer now offers a menu item View/Profile and Debug (or just press F10). We will use the viewer in the following examples but it is worth remembering that all this is available to any application using the runtime.

profui12

First, we have some quite standard information up there: (note that everything is live and updated every frame)

  • OpenGL – useful on some platforms to verify the application is indeed running against the desired implementation, or to see if the runtime is using its OpenGL ES 2.0 level reduced functionality mode (see the System Requirements page in the documentation for more in this).
  • CPU and memory usage (available on Windows and Linux (incl. Android))
  • and of course, the frame rate (with a simple, configurable visualization even).

Given that this is built-in and is rendered in-scene (so works with platform plugins like eglfs as well), and so can be brought up on any embedded device, this view alone can be quite valuable during the development phase.

The rest is a bit more tricky since some of it may need some understanding of what happens under the hood. Some of you may remember a Qt World Summit talk from last year, discussing implementing a “runtime on top of Qt 3D”. This describes the concept well and is still valid today. In short, the Qt 3D Studio editor generates .uip (and .uia) files which are XML documents describing the scene and other things.

uip example

Excerpt from SampleProject’s .uip file

(click on the images for a full size view!)

Now, before anyone gets a shock from all that XML stuff, the good news it that this is basically irrelevant. The format may change arbitrarily in the future, and could be JSON, a binary blob, or QML even (hint hint…). It is just a serialization format in its current form. What matters is the scene (and slide) trees that are then created by the runtime when parsing this input. The concept is very similar to the scene graph of Qt Quick, where the QQuickItem tree is backed by a QSGNode tree. With Qt 3D Studio the QQuickItem tree has no equivalent (yet! (hint hint…)) and we are building up a Q3DSGraphObject tree either by parsing the XML document or programatically with a (currently private) C++ API.

SampleProject scene structure

SampleProject scene structure

The (experimental) console’s scenegraph command shows this very well. Bringing up the console from the Scene Info section and typing scenegraph prints the Q3DSGraphObject tree. Unsurprisingly, this matches almost completely the scene tree in the editor’s Timeline view.

Note that at this point we still have nothing to do with actual graphics resources, APIs like OpenGL, or drawing anything on screen. We could just have stopped here, manipulate our Q3DSGraphObject tree a bit, and then maybe serialize it back to a file, without ever initializing anything graphics related. Graphics only comes in the picture in the next step:

Qt 3D entity graph

The generated Qt 3D entity graph(the Qt 3D entity graph viewer is not available in 2.0 but is already merged to the master branch and will therefore be place in 2.1 later this year)

For those who have experience with Qt 3D this probably is starting to look familiar.

Based on the Q3DSGraphObject tree, a Qt 3D framegraph and scene (entity) graph are generated and kept up-to-date in sync with any changes to the Qt 3D Studio data structures. It is then up to the Qt 3D renderer to manage graphics resources (textures, buffers) and generate draw calls based on the entity and framegraphs.

Model nodes become entities with one or more child entities (one for each sub-mesh) which have components like a material and a Q3DSMesh (a QGeometryRenderer subclass) on them, thus turning them into renderable entities. Each of these will lead to eventually issuing an OpenGL draw call (glDrawElements or similar).

The QLayer components show how the “tagging” to differentiate between the opaque and transparent (and sometimes other) passes is done in practice: the renderable entities (the ones with Q3DSMesh on them) only have one QLayer component associated since they belong either to the opaque or the transparent pass, but not both. The ancestors, like the parent “model” entity, or entities corresponding to group nodes have 2 QLayers since these are non-renderable (no draw call is generated for them) and their transform has to be taken into account in all passes.

Text is (for now) done by rendering into a QImage with the raster paint engine (QPainter) and then drawing a textured quad, as witnessed by the single entity generated for the DateAndTime text node.

This in itself does not tell much about the number or size of graphics resources. To help designers and developers getting an overview of the approximate graphics resource usage, the Qt 3D Studio runtime tracks some of the relevant Qt 3D objects it creates, in particular texture and buffer instances which under the hood lead to create OpenGL texture and buffer objects. This is what is shown in the Qt 3D Objects view:

Qt 3D object list

Qt 3D object list

  • Is the model the designer provided too complex? Seeing a lot of submeshes with lots of data in them should raise a flag right away. Such meshes may render just fine on a desktop PC but can cause performance issues on an embedded device.
  • Are we wasting time on unnecessary blending? Blending means the object belongs to the transparent pass and so the mesh is rendered with together with the other “transparent” meshes with blending enabled, sorted back-to-front. This is unnecessary and wasteful if there is in fact no need for full or partial transparency.
  • Are the texture maps too large? A quick look at the texture list can reveal another set of potential problems that may pop up when deploying to a more constrained target platform.
  • Is multisample antialiasing in use? MSAA may make things look nice on the design PC but may be too much to ask from some of the typical embedded devices today.

Pay attention to the Shares data column. Two rows in the texture list does not mean there are two OpenGL textures active. For example, using the same file as the source of more than one texture map will often lead to reusing the same data and ending up with using the exact same OpenGL texture object under the hood.

Now that we have the data to render with (geometry, shaders, textures), what is left is to define how exactly the rendering is to be done. This is ensured by generating and maintaining a Qt 3D framegraph:

SampleProject Qt 3D framegraph

SampleProject Qt 3D framegraph

This framegraph view is likely not that essential for typical users. It is most useful to those who are looking for deeper understanding and to develop the runtime.

Note that Layer Caching option in the Alter Scene section on the left. (do not confuse Qt 3D Studio layers with Qt 3D QLayers: in Qt 3D Studio a scene consist of one or more layers, each of which acts as a mini-scene with its own 2D backing store (OpenGL texture in practice), which are then composed together with a simple (or sometimes not so simple) texture blit as the last step in the rendering process – this is no different than Qt Quick layers in fact. Qt3D’s QLayer has nothing to do with this and can rather be thought of as a tag that can be attached to entities to allow filtering them.)

When there is no change in a layer (nothing is animated), there is no need to re-render the contents of it for the next frame, the existing texture contents can be used for composition as-is. This is implemented by dynamically taking out/re-adding framegraph node subtrees from/to the framegraph. This is also reflected by the live framegraph view, so to get a full overview of what the rendering of the scene involves, turn Layer Caching off temporarily.

One may wonder why there are seemingly useless QFrameGraphNode objects with a sole QNoDraw child in the tree. The reason is that subtrees may be generated inserted dynamically upon certain conditions (say a light becomes shadow casting, SSAO gets enabled, progressive AA gets enabled for a layer, etc.), and these “dummy” nodes with their no-op child leaf are placeholders.

Enough of tree views, back to the simpler tables:

SampleProject layer list

SampleProject layer list

The Layer list shows all the Qt 3D Studio layers. Each of these has one or more corresponding textures in the Qt 3D Objects view. Watch out for things like:

  • Are the antialiasing settings sane? See this documentation page for an overview of the available AA techniques. All of them come at a cost when it comes to performance and resource usage.
  • Are the Dirty and Cached values as expected? Layers that have no animations running in them are expected to be in Dirty == false and Cached == true state (thus avoiding re-rendering the contents every frame).
  • If an advanced blend mode (overlay, color burn, color dodge) is used, make sure it is really required as these involve additional resources and expensive extra blits.

Note the Presentation combo box that is present in this and many other views. Qt 3D Studio allows using multiple sub-presentations, as explained here. The contents of sub-presentations are rendered into textures which are then used either as the contents of some layer in the main presentation, or as texture maps for some material. As the main and the sub-presentations each have their own Q3DSGraphObject tree, most related functionality in the console and in the debug views is organized on a per-presentation basis. Use the combo box or the appropriate console command to switch between the presentations.

Finally, note that there is extensive qDebug output from the runtime. The debug messages are also collected and shown in the Log view. This allows easy filtering, allowing turning off uninteresting messages. The most interesting categories are q3ds.perf, q3ds.scene, and q3ds.uip.

q3ds.perf log messages

q3ds.perf log messages

Certain operations that are considered especially heavy will trigger a q3ds.perf message. This can be helpful to recognize some less optimal design choices in the presentations.

The post What’s in a Qt 3D Studio Scene? appeared first on Qt Blog.

Qt Webinar by basysKom

19 June 2018, basysKom Development Lead Frank Meerkötter and Michele Rossi from The Qt Company presented a webinar: Qt OPC UA – An Overview Driven by topics such as Industry 4.0 and IoT, OPC UA has established itself as the de facto standard for the communication of industrial devices and applications. Qt 5.11 ships with … Continue reading Qt Webinar by basysKom

Introducing Qt Automotive Suite 5.11

We are very happy to announce an updated version of the Qt Automotive Suite, a unified HMI toolchain and framework for digital cockpit, is now available.

In case you hear about this for the first time, Qt Automotive Suite was created together with KDAB and Luxoft to solve the key challenges in HMI creation for digital cockpits in automobiles. With combinations of world class tooling, automotive specific software components, and highly optimized software framework for embedded devices, we are solving those challenges and offering the world’s end-to-end HMI solution with a single technology.

In Qt Automotive Suite 5.11 we have a major upgrade for the 3D tooling, complete overhaul of our reference UI and improvements on automotive components. All of these are built on top of Qt 5.11 series, bringing the cutting edge of what Qt Automotive Suite offers.

Faster, better, stronger

For those of you who are already familiar with Qt Automotive Suite releases, you might have noticed immediately that we no longer maintain its own version number. Good catch! Since the release of Qt Automotive Suite 2.0 this year, we decided to make new releases following Qt’s release schedule. That way, every Qt Automotive Suite future release can benefit new features and improvements from each Qt release, and more importantly we can now make new releases more frequent.

With mere four months time between Automotive Suite 2.0 and 5.11 releases, we are very pleased to see more OEMs and Tier1s took interest, and quite a few of them adopted it for developing their next generation digital cockpit platforms. Once again proving that OEMs and Tier1s would like to consolidate into one technology for the entire digital cockpit HMI development.

What’s new?

So, what is in Qt Automotive Suite 5.11? The most visible part of the new release is the new reference UI. The reference UI is not a showcase for the capabilities but actually a starting point for iterative development either in the UI or underlying functionality.

neptune-digital-cockpit

Figure 1. Neptune Reference UI

Qt Automotive Suite 5.11 comes with a major overhaul of Neptune Reference UI and a new User Experience design. There are now three parts in this Reference UI: an instrument cluster, an IVI, and a mobile app for remote control. It forms the minimum building blocks for the digital cockpit HMI where the instrument cluster is for the driver, in-vehicle infotainment is for the driver or passenger, and a mobile app that the driver or passenger can custom their favorite settings remotely.

So how Automotive Suite was used to build the Neptune UI? You will find more detail in the “Neptune Reference UI in depth” section. Let’s look at Automotive Suite architecture.

qtas5-11_sw_arch

Figure 2. Qt Automotive Suite Architecture

In summary, the above diagram reflects our vision to provide easy-to-use tools that free designers and software engineers to rapidly create superior digital cockpits.

Qt for Device Creation 5.11

Of course, Qt Automotive Suite 5.11 sits on top of Qt 5.11, bringing major performance improvement and new feature set.

Qt 3D Studio 2.0

We believe a truly unified HMI toolchain and framework should also ship with advanced UI authoring tool for the designers. With 3D becoming a more significant part of the HMI we saw the need for a design tool that facilitates rapid 3D UI/UX concepting and design. With Qt 3D Studio 2.0, we have now all new 3D rendering engine and a great number of improvement on the usability and features. Have a read at Qt 3D Studio 2.0 blog.

Check out our latest cluster demo (codename Altair) implemented by 3D Studio 2.0.

Qt Safe Renderer 1.0

Functional safety is a critical path that our customers must cross. Qt Automotive Suite 5.11 includes the Qt Safe Renderer, which is now certified by ISO 26262 part 6 up to ASIL-D specification. If you missed the announcement, be sure to check out here.

Qt Application Manager

Qt Application Manager brings a modern multi-process GUI architecture to the IVI. By separating the HMI into different functional units (for example, HVAC could be one unit while Navigation could be another), Qt Application Manager enables independent teams to develop and test both separately and simultaneously, thereby reducing project risk and shortening development time. In addition, splitting the UI into smaller applications also makes it easier to do system updates; smaller pieces of code are touched, and the OTA updates are smaller. To learn about Qt Application Manager, check out the documentation at: https://doc.qt.io/QtApplicationManager/index.html

With Qt Automotive Suite 5.11, Application Manager has received updates highlighted as follow:

  • Improved performance monitoring and profiling API that now supports GPU utilization.
  • QtObject can be the root element of an app or a System UI, thus improving the multi-window support.
  • We’ve also added support of OpenSSL 1.1 as required in Qt 5.11
  • There is now support for extra meta-data in application packages, which enables new features in future releases of the Deployment Server (previously known as “App Store Server”).

Qt Application Manager Plugin for Qt Creator

Since Qt Application Manager controls the application lifecycle, a direct launching from Qt Creator is not possible. A special plugin is provided now which wraps the command line tools provided in Qt Application Manager and integrates all essential steps into Qt Creator IDE. In Qt Automotive Suite 5.11, we have improved our documentation and the plugin stability.

Qt IVI

To tackle reusability, QtIVI brings a level of standardization within the Qt ecosystem for how to access and extend automotive-specific APIs. The applications developed in one generation of a program can be reused on the next, even if the underlying platform is different. This is particularly important as OEMs are increasingly taking control of the car HMI development, reducing duplication of work means significant cost saving and more focus on brand UX differentiation. Qt Automotive Suite is designed to integrate well with industry’s leading initiatives such as GENIVI and AGL, further increasing the reusability on the platform level for the entire industry. More detail can be found here.

With Qt Automotive Suite 5.11, Qt IVI has received updates highlighted as follow:

  • In Qt Automotive Suite 2.0, we introduced the use of IVI APIs auto-generated from IDL files written in QFace. In 5.11, it also can also use QtRemoteObjects as an IPC provider. The latter allows further modularization of the IVI middleware across multiple processes with clear benefits in stability and a cleaner architecture.
  • To make it easier to write and maintain the templates for the “ivigenerator”, a common template folder has been introduced. With this change we also introduced common Jinja macros, which removes a lot of common boiler-plate code in our macros.
  • The “ivigenerator” now also supports additional annotation files. This can be useful if multiple parts are generated from the same QFace file, whereas every project needs different annotations.
  • A new “QIviPendingReply” class was introduced. This class is a QFuture/Promise like API which can be used from C++ as well as from QML and is used to provide the return value of a function in an asynchronous manner. This is already fully integrated into the new QtRemoteObject based generator templates.

Comprehensive documentation

Without exception, we continuously improve our documentation. Qt Automotive Suite 5.11 comes with more comprehensive documentation and examples for most of development needs.

Summary

With Qt Automotive Suite 5.11, we have further strengthened our offering for the truly end-to-end solution for the digital cockpit HMI development. We brought in all new Qt 3D Studio 2.0 with many of the needed changes for automotive HMI designers, we added the fully certified Qt Safe Renderer for addressing the functional safety. We revamped the Neptune Reference UI that provides modern reference to digital cockpit design, and showcased how easy is to build digital cockpit with Qt Automotive Suit. We made significant number of improvements on all our software components. Finally, many thanks for the feedback especially from our customers and prospects.

 

 


Neptune Reference UI in depth

IVI

To highlight the multi-process UI capability of our Qt Application Manager, we redesigned the System UI with a strong focus on what’s possible with multi-process UI paradigm

qtas-ivi

Figure 3. Neptune IVI with focus on multi-process UI

As depicted by the figure above, we now introduced a new concept of “App Widgets” shown on the System UI, while each app widget runs in its own process implemented in Qt Application Manager. User can freely move each app up and down, open or close the app. When you resize the app window, the app will automatically display the right content based on window size, thus addressing the popular trend called Response UI.

We have added theming and accent color to the IVI settings, so a user can select dark and light theme with multiple accent colors, thus provides reference to how Qt Automotive Suite enables theming capability.

qtas-theming

Figure 4. Theming and color accent

For navigation and mapping, we now leverage the Qt Location Mapbox GL Plugin, which provides the Mapbox mapping and styling by following Neptune UI theme and styles.

qtas-mapbox-gl-plugin

Figure 5. Mapbox GL plugin from Qt Location

The Vehicle application now contains an interactive 3D car model and adds controls visualizing user actions via manipulations of 3D objects via QML API. All this is completely based on Qt3D and so demonstrates that no additional software is required to visualize 3D objects in automotive use cases.

qtas-3d-car

Figure 6. 3D car model and seamless integration with QML control

Instrument cluster

On the instrument cluster side, user can now share the content shown on the IVI onto the instrument cluster screen. Also, Qt Safe Renderer has been used to render the tell-tales as separate process via RTOS and hypervisor.

qtas-cluster

Figure 7. instrument cluster gets the Mapbox view shared by IVI

Inter-domain and inter-process communication

To cater the need for inter-process and inter-domain communication, we implemented a new Remote Settings Server based on Qt Remote Objects, which can serve multiple clients running on the same host or remote instances. For example, our new mobile app called “NeptuneControlApp” is capable of running on a mobile device. The app can communicate to the Remote Settings Server, and a user can, for instance, change the language of the digital cockpit as well as many other settings that are accessible. Perhaps the best part of the app is that it shares the auto-generated code base with Neptune UI and the Setting Server, thus matching to exposed setting options without manual work.

qtas-mobile-app

Figure 8. Remote Control App for Android and iOS

Check out the documentation at: https://doc.qt.io/Neptune3UI/index.html.

The post Introducing Qt Automotive Suite 5.11 appeared first on Qt Blog.

Qt Design Studio – The New Age of UI Development

Today, I am extremely happy to make a special product announcement.

Together with Qt 3D Studio 2.0, we are also releasing our newest and hottest addition to the Qt design tool family: Qt Design Studio

Qt Design Studio is a UI design and development environment that enables designers and developers to rapidly prototype and develop complex and scalable UIs.

I bet all of you have run into typical challenges when collaborating with either designer or developers, depending on your role.

Developers often see designs evolve in an ivory tower and then land on their desks as long and detailed PDFs with UI specifications. Sometimes, this happens after the initial effort estimates have been done. Most of the time, matching the UI specifications with what can be achieved on the target hardware is dubious and time-consuming. Equally time-consuming is the “negotiation” process with designers, which means compromising and refining under tight project schedules. That does not bode well for the quality of the final product.

Designers, on the other hand, are mostly concerned about coming up with the best design they can think of – their design vision. What’s possible in reality can be hard for them to fathom until they see their designs come to life on the actual device. They want to be able to evolve the designs by testing new approaches in minutes, instead of waiting at worst weeks, to see the design iterations run on the real hardware. Designers typically also want to test the designs on the device with real users as soon as possible, which can often fall by the wayside due to time constraints.

The real problem, however, is that this inefficient way of working causes the end user to pay the ultimate price in worse overall user experience.

unknown

We believe that collaboration between designers and developers in an effective workflow fosters and boosts product innovation and ultimately leads to a better user experience.

Enhanced workflow with Qt, QML, and Qt Design tools

Qt Design Studio is a single tool used by both designers and developers. That alone makes collaboration between the two a lot simpler and more streamlined: Designers can look the graphical view, while developers can look at the QML code. With this workflow, designers can have their Photoshop designs running on real devices in minutes!

Qt Design Studio features in more detail:

  • Qt Photoshop Bridge – Create your UI design and UI components in Photoshop and import them in Qt Design Studio. This is an advanced Photoshop plugin that exports your designs to Qt Design Studio where it is translated into QML.
  • Timeline-based animations – Creating advanced animations was never simpler. The timeline-/keyframe-based editor lets designers create pixel-perfect animations of any type without having to write a single line of code.
  • QML Live Preview – Run and preview your application or UI directly on the desktop, Android devices, and Boot2Qt devices. See how your changes affect the UI live on your target device in minutes!
  • QML Visual Effects – Apply out-of-the-box visual effects to your designs, e.g. blur, colorize, glow, and more. You can even animate the effects with the Timeline editor.
  • QML Shape Items – Several out-of-the-box shapes, i.e. Pie, Arc, Triangle, etc. are ready for prototyping and building custom QML visual elements.
  • Manage and create custom re-usable components – Turn your Photoshop layers into reusable components for different projects with but a few clicks.
  • and many more… e.g. manage layouts and states with ease

These key features will be finalized and polished for the 1.0 version, which is scheduled to release by the end of the year. Meanwhile, the technical preview release already contains most of the key features in fairly good shape. We’re more than happy to receive your feedback during this technology preview period.

Where can you get it? Head to our Qt Design Tools webpage, and click the “Free Tech Preview Trial” button under 2D Feature Highlights. This will sort you with a download link for your 10-day trial. You can always contact us if you want to extend the trial.

We have also created a set of how-to videos that will guide you through all the features and capabilities and show you in practice hands-on how to design and develop a UI with Qt Design Studio.

Our plan is to introduce Qt Design Studio as a free tool for all our commercial term license holders. You don’t need a valid commercial license for the tech preview. You will, however, need a valid commercial term license if you want to distribute the applications you have created with Qt Design Studio tech preview. We are also looking into open source options. We’ll share more information on that as it becomes available.

Last but not least, to learn more about Qt Design Studio and keep abreast with what’s in store in the future, make sure to watch our on-demand webinar!

The post Qt Design Studio – The New Age of UI Development appeared first on Qt Blog.

Qt 3D Studio 2.0 released

We are happy to announce that the Qt 3D Studio 2.0 has been released. We are making this release together with our newest addition to the Qt design tool family: Qt Design Studio.

To get an overview of what is new in Qt 3D Studio 2.0, see live demos and ask questions, sign up to the upcoming webinar.   

Editor

From UI designer perspective the 2.0 release contains a lot of usability improvements. For example the 3D design view has now a gradient background which makes it easier to see the orientation of viewport. Camera and Light objects also have a better visualization which makes it easier to see the effects of the property changes for these objects. Also the 3D object manipulators have been improved so that rotating, scaling and moving accuracy is now much better. Also selecting and deselecting items is now more logical. Keyboard and mouse handling has been also changed so that you can for example now Pan, Zoom and Orbit with Alt key + mouse button combinations.

3D Desing View

3D Design View

Also the interaction between application logic and UI can be now fully defined by using the Data Inputs which we introduced as technology preview in 1.1 release. Mechanism for doing this has remained the same i.e. the Qt 3D Studio project defines what kind of data the UI needs and these data items can be added with Data Input dialog (under File menu).

Define and link data inputs to UI

Define and link data inputs to UI

The Data Inputs are then tied to different properties or timeline to control object property changes or animation timeline from the application logic.

Runtime

The 2.0 release introduces the new Qt 3D Studio runtime built on top of Qt 3D module. This means that the whole rendering engine has been rewritten with Qt and it now follows the normal Qt module practices. This is a big milestone from the further development perspective as with the new code base adding new features and maintenance is easier. To make sure that that we haven’t introduced regressions between the new and the old runtime we are still shipping the old runtime as part of the 2.0 release. You can enable the old runtime Viewer application from the Edit – Studio Preferences menu by enabling the Legacy Viewer option. After that you will get an additional Play button to the toolbar for launching the old Viewer. If you are experiencing differences between the runtimes please file a bugreport to https://bugreports.qt.io

Getting started

Qt 3D Studio 2.0 is available through Qt online installer under the Tools section. We also provide standalone offline installers which contain all you need to start designing Qt 3D Studio User Interfaces. Online installer also contains pre-build runtime for Qt 5.11 which is needed for developing Qt applications using Qt 3D Studio UI. Qt online installer and offline installers can be obtained from Qt Download page and commercial license holders can find the packages from Qt Account. Binary packages are are available for Windows and Mac. For further information about how to get started please refer to the Getting started documentation and Laszlo’s blog post Get Started with Qt 3D Studio 2.0 beta 1.

Some example projects can be found under examples folder in the installation directory. Additional examples and demo applications can be found from https://git.qt.io/public-demos/qt3dstudio repository. If you encounter issues with using Qt 3D Studio or you would like to suggest new feature, please use Qt3D Studio project in the https://bugreports.qt.io

Be sure to sign up to the webinar now and tune in to find out all about Qt 3D Studio 2.0. Watch some cool demos, and ask your questions live!

The post Qt 3D Studio 2.0 released appeared first on Qt Blog.

News from installer team

We have now released Qt Online installer and Maintenancetool version 3.0.5. Especially, the metadata download has been improved. Metadata is downloaded now in smaller chunks as in some devices the metadata download got completely stuck due to huge simultaneous download tasks. You see this in UI as external step counter above scrollbar.

ui

Another major improvement in metadata download is that we have managed to decrease the amount of metadata approximately 25%.
Currently we are implementing a feature that allows categorizing Qt releases and to show only selected categories in UI. User can decide which category is wanted to see in UI and only those items’ metadata is downloaded making the metadata download part much faster. So improvements have been done and more is coming. Here is a hint what the category UI will look like. Note that the work is still ongoing and we are not going to see this yet in 3.0.5 release:

categories

The post News from installer team appeared first on Qt Blog.

Integrating Cloud Solutions with Qt

Welcome to the final installment of our Qt for Automation blog mini-series. If you missed the previous articles, please have a look at Lars’ blog post, where you can find an overview of all the topics (remote UIs, optimizing device communication, and more) we’ve covered.

These days, using the cloud for predictive maintenance, analytics or feature updates is a de facto standard in the automation space. Basically, any newly designed product has some server communication at its core.

However, the majority of solutions in the field were designed and productized when communication technology was not at today’s level. Still, attempts are being made to attach connectivity to such solutions. The mission statement is to “cloudify” an existing solution, which uses some internal protocol or infrastructure.

Let’s consider our favorite example in this series, the Sensor Tag demo. Multiple sensors publish their telemetry data to an MQTT broker. If this infrastructure cannot be changed, a cloud-based solution needs to be attached to it, like in the graphic below:

cloud_connector

The first thing we need is a connector, which translates internal protocols and payload-formats into what a cloud solution accepts as valid input.

So, let’s create one!

One of the great features in Qt is that you can connect to any cloud solution provider. Whichever you chose, the principles in this post will be the same. We are going to use Microsoft Azure and its IoTHub solution in our example.

The demo contains a topic called “sensors/active”. Each active device continuously reports itself as available on this topic. If a connection is interrupted or the device disconnects, a retained message is sent indicating the offline state. This is going to be the entry point for the connector.

Subscribing to that topic is done with QMqttClient::subscribe

 

m_activeSub = m_client->subscribe(QLatin1String("sensors/active"), 1);


Each time a new client goes online, a new SensorInformation instance is created. The sensor is stored in conjunction with its ID in a map.

[...]
    if (split.at(1) == "Online" && !m_sensors.contains(split.at(0))) {
        const QString subName = QString::fromLocal8Bit("sensors/%1/#").arg(QString::fromUtf8(split.at(0)));
        auto sub = m_client->subscribe(subName, 1);
        if (!sub)
            return;

        auto sensor = new SensorInformation(sub, this);
        connect(sensor, &SensorInformation::publishRequested, m_azure, &AzureConnection::publishMessage);
        m_sensors.insert(split.at(0), sensor);
[...]

Additionally, the SensorInformation stores the subscription and parses the received messages. Periodically (or whenever a single value changes) the device state requests a sync to the cloud via the publishRequested signal.

The IoTHub expects messages to have its payload formatted as JSON. As demonstrated in our previous posts of this series, this is a simple task using Qt, and more specifically, QJsonDocument.

To send messages to Azure, a thin layer around the IoTHub SDK is created to hook into Qt. A minimalistic approach looks like this:

class AzureConnection : public QObject
{
    Q_OBJECT
public:
    AzureConnection();
    ~AzureConnection();

    void init(const QString &connectionString);
    void cleanup();

Q_SIGNALS:
    void messageReceived(const QByteArray &content);
    void messageSent();
    void messageError();

public Q_SLOTS:
    void publishMessage(const QByteArray &content);

private:
    AzureConnectionThread *m_thread;
};

Azure expects each connection to have a unique ID to identify the account, the device and the session. In this example, we expect this string to be known beforehand. An API exists to do device provisioning to Azure, but that is not part of this article.

The initialization is handled via

    if (platform_init() != 0)
        return false;

    m_iotClientHandle = IoTHubClient_LL_CreateFromConnectionString(qPrintable(connectionString), AMQP_Protocol);
    if (m_iotClientHandle == NULL)
        return false;

    IOTHUB_CLIENT_RESULT receiveEvent = IoTHubClient_LL_SetMessageCallback(m_iotClientHandle, ReceiveMessageCallback, this);
    if (receiveEvent != IOTHUB_CLIENT_OK)
        return false;

    return true;

The SDK itself handles everything via callbacks, more specifically the message state. Once a message is sent by calling IoTHubClient_LL_SendEventAsync() the state of the message is handled in a callback. The various options are handled in SendConfirmationCallback()

    EVENT_INSTANCE *eventInstance = (EVENT_INSTANCE *)userContextCallback;
    switch (result) {
    case IOTHUB_CLIENT_CONFIRMATION_OK:
        qDebug() << "ID: " << eventInstance->messageTrackingId << " confirmed";
        break;
    case IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY:
        qDebug() << "ID: " << eventInstance->messageTrackingId << " not confirmed due to destroy";
        break;
    case IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT:
        qDebug() << "ID: " << eventInstance->messageTrackingId << " not confirmed due to timeout";
        break;
    case IOTHUB_CLIENT_CONFIRMATION_ERROR:
        qDebug() << "ID: " << eventInstance->messageTrackingId << " not confirmed due to confirmation error";
        break;
    default:
        qDebug() << "ID: " << eventInstance->messageTrackingId << " Unknown confirmation";
        break;
    }

Once a message has returned the confirmation state, it has been parsed and processed by the IoTHub. Any previous state indicates that it has not yet been stored and is cached locally.

After the messages have been confirmed, analytics (or any other operation) can be applied to the data (eg. TimeSeries Insights or the new IoTCentral products). Check out the custom dashboard in our demo video at the Embedded World 2018:

This example uses one executable to handle all available sensors. Naturally, a highly scalable setup demands further requirements. Given that the presented Qt connector runs on a server instance already, it could easily be integrated into a virtualization scenario using containers or similar.

As you have seen, not only can you use Qt to create devices and gateways with and without an HMI, but also bridges between various aspects of a deployment setup. With a consistent API, all building blocks can easily be moved, while the code stays the same due to its cross-platform capabilities.

The post Integrating Cloud Solutions with Qt appeared first on Qt Blog.

qutebrowser v1.3.3 released (security update!)

I've just released qutebrowser v1.3.3, which fixes an XSS vulnerability on the qute://history page (:history).

qutebrowser is a keyboard driven browser with a vim-like, minimalistic interface. It's written using PyQt and cross-platform.

The vulnerability allowed websites to inject HTML into the page via a crafted title tag …