Qt Internationalization – Create Your UI Using Non-Latin Characters

People, ideas and data are moving all around the world nowadays, and so are your applications! Developing a UI in one language only, regardless of the platform is not an option anymore. Now if you are lucky enough to be using Qt, this is achievable with little effort, even when dealing with non-latin characters and “right to left” languages.

This tutorial will guide you towards this goal with your Qt Quick application and will hopefully give you some, useful tips!

Phase 1: Translation Files and Iupdate

1.1 Generate Your Translation File in Qt

The first thing to do is to translate your application. It means you have to take all the static strings in your application and replace them with the translated version at the right time.

In Qt, this is first done by declaring translations files and using translation methods (tr, qsTr, QT_TR_NOOP). Your application will require exactly one translation file per supported language.

This is how you have to modify your project file and QML files to enable extraction the strings to translate:

MyProject.pro

TRANSLATIONS += \
    translations/en-US.ts \
    translations/zh-CN.ts \
    translations/ar-MA.ts \

lupdate_only {
    SOURCES += \
         main.qml\
         MainPage.qml
}

main.qml
Windows {
    width: 800; height: 480
    title: qsTr ("My Application Title")
}

If you are wondering about the “en-US” notation, it corresponds to IETF language tags (https://en.wikipedia.org/wiki/IETF_language_tag). It is the juxtaposition of the language and country code and is often used to identify languages and locale.

Also, note we used ‘lupdate_only’ conditional in order to add our QML files to SOURCES only for the lupdate step. The SOURCES variables are used to compile your .cpp files, but they also happen to be used by lupdate to extract the translations.

At this point you can manually generate the translation files in QtCreator using “Tools > External > Linguist > Update translations (linguist)”. This will regenerate .ts files after parsing all files from the SOURCE variable of your project. You will end up with three .ts files (XML format) in your project, containing your new untranslated string “My Application Title”, its context (i.e. file) and its line number.

1.2 Now Apply Your Translation

You can then apply a translation.

Instantiate a QTranslator class, and use the QCoreApplication::installTranslator() method.

QTranslator *arabicTranslator = new QTranslator (":/translation/ar-MA.ts");
qApp ->installTranslator (arabicTranslator);

More than one translator can be installed at the same time. Qt will translate your strings using the last applied translator, and sequentially the next ones until it succeeds… or not. If not your original string will be displayed as it is written in your code.

Window {
    width: 800; height: 480
    title: qsTr ("My Application Title")
}

Phase 2: Translation at Runtime

Another common request is to dynamically retranslate the user interface. Changing the translator at runtime is quite simple, but updating the strings to reflect that modification may be a bit more challenging.

Fortunately, Qt provides QEvent::LanguageChange event for that purpose.

It is generated when you apply a new translator. This is what you will use for Widget based applications, along with the retranslateUi method for Designer generated UIs.

However, this is not very convenient and I found there is another simple solution.

  • Expose an empty QString property, trTrigger in our case
  • Bind your texts with this property like ‘text:qsTr(“My text”) + app.trTrigger
  • Emit trTrigger “changed”signal every time the language changes

You will get the full expression being re-evaluated (hence retranslated) while keeping the text unaffected.

main.qml
Window {
     width: 800; height: 480
     title: qsTr ("My Application Title") + app.trTrigger
}

Phase 3: Supporting Chinese, Arabic, and Others

This is where font and text encoding become important. You may already have stumbled upon related issues when copy-pasting special characters from another document, only to discover they were replaced by unreadable ones. The two usual suspects are the Font and the Encoding of your document.

  • An incorrect encoding won’t be able to store or translate the characters correctly
  • An incorrect font won’t be able to render the characters

For example, Ask Comic sans MS to tell you “你好!”, and it will just fail. If this happens (and it probably will), it simply means your system or software uses a different or fallback font. This fallback font is used to render Chinese, despite the fact the original font does not support Chinese characters. And this is exactly what Qt will do when possible, saving you some work!

That’s why for the best visual outcome you will need to include fonts that are compatible with the language you want to support. If you then package these fontswith your application, you can easily install them dynamically using the QFontDatabase, or FontLoader on QML side.

On Linux platform, just make sure you have a fontloader library installed and available otherwise it won’t work. The encoding is less explicit than the font. It applies to files and variables storing your text. As long as you stick with QString for display and Qt translation mechanism you should be fine. But when you manipulate non-ascii characters you will have to take a few precautions:

  1. In files, make sure that encoding supports the characters you use (UTF-8 is a good default choice)
  2. In variables, make sure that it supports such characters (e.g. std::wstring vs std::string).

As for classic Qt translation, you will have to provide the corresponding .ts file to the person in charge of translations (e.g. “translations/zh-CN.ts”), as well as the linguist application from your Qt folder (e.g. “C:\Qt\5.8\mingw53_32\bin”).

Yes, I used a Windows path as an example, because I doubt that people working on your translations will be able to run linguist from your custom Linux distribution Linguist is a standalone application, so translators won’t need to install Qt, don’t worry.

This standalone application allows loading and saving .ts files, once the translations are done.

Witekio Qt Linguist Chinese

Now ask your translator to send you the .ts file modified: you’re done!

Phase 4: Don’t Forget that Right to Left Is Not Only a Text Thing

User interface composing is where the biggest difference compared to Left-to-Right languages lies.

In Arabic and Hebrew, you read and write from the right side to the left, and this has a significant impact not only on the text but on your whole application including:

  • Text alignment (right aligned by default!)
  • Menus and components position
  • Writing direction
  • Lists direction

In a way, this is like flipping your entire UI layout horizontally. Qt will locally help you change text alignment based on the character set used, but you will have to anticipate and implement the global strategy.

At the application level, you have the “setLayoutDirection” method. It is typically set from the application language, but you can also do it manually with:

qApp->setLayoutDirection (Qt::RightToLeft);

Qt Quick application then provides different ways to deal with layout direction. QML Layouts have the layoutDirection property, Images have the mirror, and all Items have the very powerful LayoutMirroring attached property.

”LayoutMirroring” is a fast way to change the direction of layouts, positioners (Row, Grid, …), anchors and text alignments, of the item and its children with only two lines:

Page {
     LayoutMirroring.enabled: (Qt.application.layoutDirection === Qt.RightToLeft)
     LayoutMirroring.childrenInherit: true
     Row {
         // Row will use right-to-left order when LayoutMirror.enabled = true
         Text {
              id: songNumber
              text: "1."
              horizontalAlignment: Text.AlignLeft // Alignment will adjust too. But don't fail to mention it         
                                                  // or the text won't change its alignment
         Text {
              id: artistItem
              text: "Some Artist"
              horizontalAlignment: Text.AlignLeft
              // Manually change elide side
              elide: (Qt.application.layoutDirection === Qt.LeftToRight) ? 
Text.ElideRight : Text.ElideLeft
         }
    }
}

LayoutMirroring.childrenInherit will apply the mirroring to all the children, making it a very efficient way to apply it. However be careful as it will very likely break some parts of your UI if you have not built it from the beginning with “Right-to-Left” and “Left-to-Right” in mind.

The example below shows the difference between standard English version and Arabic right-to-left version. Note that not only the text alignment is changed, but also the layout and the “+” and “-” buttons. This may look odd to some of you, but remember that right-to-left languages are not only about the text, but also the way eyes scan the content of the application.

Witekio | qt-application-english et qt-application-arabic-rtl

 

How Can You Make Chinese, Arabic, and Left-To-Right Integration as Easy as Possible? Wrap Up!

  • Use Qt Linguist and QTranslators for translations
  • Pack the fonts you want to use in your application for Chinese, Arabic, etc and install them with QFontDatabase or Fontloader
  • Do not use absolute positioning (the default “x:O” does count as such!)
  • Do use Layouts and positioners
  • Do use anchors and anchors margins
  • Do set Text.horizontal Alignment property

Qt provides you with a good start for integrating a lot of languages. With a bit of work and anticipation, your application will be understood all over the world. The key to an efficient integration of Right to Left languages is simply to plan and test it early during application development, to ensure it is fully compatible.

On embedded devices, don’t forget that Chinese, Russian and Arabic, only to name a few, need more than a simple keyboard layout, but also a way to “compose” different words based on what was typed. This is critical if you created your own virtual keyboard.

People will not be able to write in these languages simply with a different keyboard layout. Hopefully, the Qt Virtual Keyboard (Commercial or LGPLv3 license) does provide such specific input method, if you are not willing to redevelop it for yourself.

Another way is to use a carefully selected iconography. Symbols may not have exactly the same meaning in all countries, but if carefully picked up, they can help you keep your UI simple and clear.

And guess what? Resources (like images), paths and names can be translated too!

website: www.witekio.com  –  blog: www.witek.io

The post Qt Internationalization – Create Your UI Using Non-Latin Characters appeared first on Qt Blog.

The Qt Project and Google Summer of Code 2018

This year, for the first time, the Qt Project will be participating in the Google Summer of Code initiative.
This is an awesome opportunity for students who are interested in or are already involved with Qt development, and who want to flip bits and not burgers during their summer break!
What this means in practice is that by submitting a strong project proposal to the initiative, you as a student have a good chance to get a nicely paid summer job working on new features or improvements to Qt!

How to participate

For students, the recommended approach to participate in this initiative with the Qt Project is to start off by reading up how the whole thing works. Then, come up with a project idea (or choose one of the suggested ideas in the Qt Project’s wiki page), and reach out to mentors as soon as possible in our dedicated channels (in #qt-gsoc IRC channel on the Freenode network, or through the development mailing list).

In these channels you can discuss your idea with mentors (and the community), then get started, with the help of the mentors, to write down your project proposal and finally submitting it. The deadline for the submission of your proposal is the 27th of March.

Hope this sounds like an interesting opportunity and we hope that you will participate in making Qt even better!

The post The Qt Project and Google Summer of Code 2018 appeared first on Qt Blog.

Qt Roadmap for 2018

Qt 5.9 LTS is a solid baseline, which continues to improve still during 2018. Qt 5.10 was released in December, but there is more cooking. We are currently finalizing the Qt 5.11 release for May and looking towards Qt 5.12 LTS in November. In addition to the Qt framework we are actively developing our tooling offering. Tune in for an overview what we have in the works for 2018.

This blog post is a continuation of roadmap posts I have written for 2016 and 2017. As always, there is more to tell than what reasonably fits in a blog post, but I will try to talk about the most interesting items. There will be many more blog posts, videos, webinars and of course product releases throughout 2018 to provide details of the numerous items we are developing. Just like in the earlier posts, I would like to thank each and every Qt developer for their contributions. Most of the functionality is created by The Qt Company, but we also have a great ecosystem with many contributors. They have provided multiple extremely valuable contributions throughout the years and continue to shape Qt also in the future. In addition to those contributing code, we have also a large number of people active in the Qt Project forums, on mailing lists, as well as reviewing code and testing the Qt development releases. Together we create Qt!

Timelines for Qt 5.11, Qt 5.12 LTS, a lot of great tools and more

For 2018 we are planning to have two Qt feature releases: Qt 5.11 in May and Qt 5.12 LTS (Long Term Support) in November. As usual, we offer pre-releases for testing the new features. We will also create patch releases for these to address issues reported by users. In addition, we continue to make Qt 5.9 LTS patch releases throughout 2018.

For Qt Creator we are planning to have three feature releases: Creator 4.6 in March, Creator 4.7 in July and Creator 4.8 in November, providing incremental improvements and new functionality for our awesome IDE. The latest addition to our tooling offering, Qt 3D Studio, is planned to release a major new version in June: Qt 3D Studio 2.0 with new runtime based on Qt 3D. During the second half of 2018, we are planning to release Qt 3D Studio 2.1 in September and Qt 3D Studio 2.2 in December.

For our industry offering we continue to develop Qt for Automation and Qt Automotive Suite further. A major new version, Qt Automotive Suite 2.0, is planned to be released soon, followed by incremental update releases. We are also introducing new Qt Safe Renderer 1.0 for use in safety critical applications of Qt.

So, a busy year ahead of us. Now, let’s dive a bit into the features and functionality included in these releases.

What is coming with Qt 5.11 and Qt 5.12 LTS

Qt 5.9 LTS has been a solid baseline with multiple patch releases providing bug fixes and other improvements. We have already fixed over one thousand user reported issues with the Qt 5.9.x patch releases and intent to continue these during 2018. Qt 5.9 LTS has recently entered the Strict phase, which means we will fix the most important bugs, but the less important fixes will be targeted to Qt 5.11 (and later 5.12 LTS). In addition to continuously improving the quality, we are actively focusing into performance of the key use cases. We are constantly measuring performance in order to identify commits that have caused a performance regression in some area – and we also improve performance whenever possible. With the focus in both fixing bugs and improving performance, new Qt releases run the existing applications faster and more reliably.

When it comes to new features, we have many things ongoing related to graphics, so I’ll start with that. One of the biggest things for 2018 is the unification of our 3D engines. Qt 3D Studio 1.x releases use the 3D engine contributed by NVIDIA. While it is a good and solid engine, the benefits for migrating on top of Qt 3D are clear: easier to use both pre-defined and programmatically created content in the same application, improved support for different operating systems and hardware, and of course also avoiding the need to develop and maintain two different 3D engines.

Activities for being able to run Qt 3D Studio applications on top of Qt 3D have been ongoing for a long time and there are quite many improvements also to Qt 3D itself done during the process. Some of these are the improvements done to Qt 3D performance and reducing memory consumption of Qt 3D needed to efficiently run complex Qt 3D Studio applications on top of it. A great example of the benefits of unification is that these performance improvements to Qt 3D benefit also the existing Qt 3D applications – in addition to the upcoming Qt 3D Studio 2.0 applications.

Another major item for graphics is asset conditioning, essential for being able to reach optimal performance on target hardware. Both for 2D and 3D graphics, the size of assets is often a significant part of the overall application size and especially runtime memory footprint. During 2018 we continue to improve the asset conditioning support in Qt by adding more supported texture compression and packaging formats and making it easier to handle the graphical assets in build system and tooling.

Basic support for ETC1, ETC2 and ETC2_EAC compression was added already with Qt 5.10. Qt 5.11 improves the texture compression implementation and adds support for the commonly used KTX (Khronos Texture) texture file format. Modern GPUs with OpenGL ES 3.x support can handle the compressed textures efficiently, leading into improved memory usage and performance with the new Qt versions. We aim to continuously improve the asset conditioning capabilities of Qt and are currently looking into texture atlassing and other possibilities in order to further improve the performance and memory usage of textures.

Other areas we are working within the graphics are improved support for Vulkan and introduction of initial Metal support with Qt 5.12. We have also been looking into support for hardware graphics layers especially when using Qt Wayland. This is still quite hardware specific, but we have already enabled it with some commonly used SoCs.

Completely renewed gesture handling a.k.a. Pointer Handlers as a new approach for mouse, touch and gesture event handling is a major area we have been working on for quite some time now. The main issue addressed with the new functionality is versatility especially in multi-touch and multi-monitor applications, which is an area where the previous functionality has not been enough to tackle all aspects. The new functionality enables implementing other kinds of control mechanisms in Qt applications, for example based on hand gestures detected by a camera or a proximity sensor.

Pointer Handlers provide lightweight declarative API for recognizing and handling the most common mouse, touch and multi-touch gestures (press-hold-release, drag, swipe, and pinch) from mouse and touchscreen, in parallel across the scene. You can interact with multiple Items simultaneously, across multiple screens when necessary. First introduced as a Qt Labs feature, this is planned to graduate to a fully supported feature with Qt 5.12. Pointer Handlers can be extended to handle more use cases and are intended to have a public C++ API in upcoming releases.

Qt Quick Controls 2 received the initial capability for image-based styles with Qt 5.10. We are looking forward to completing the offering in Qt 5.11 and new design templates, including a template for Inkscape (in addition to Sketch, Illustrator and Photoshop templates). We are also well in progress for a new, performance optimized, table view implementation for Qt Quick, aiming to land in Qt 5.12. The target is to offer the new table view as a patch to be tested on top of Qt 5.11 in order to get early feedback. The implementation is done from the ground up with performance in mind, and we believe it is now on a good level.

So, quite many new things for Qt Quick users, but not to worry – we have not forgotten users of Qt Widgets. On the contrary, already during the past year we have been increasingly addressing open bugs of Qt Widgets and intend to continue doing so during 2018 and beyond. Both Widgets and Qt Quick have their strong points and they complement each other nicely as fully supported parts of the Qt offering.

Qt WebEngine, our HTML5 engine based on Chromium, will get an update to Chromium version 65 with Qt 5.11. For Qt 5.12 LTS we are looking into possibilities for decoupling Qt WebEngine from Qt release schedules to allow more frequent updates of Qt WebEngine. This is still under research, but there seem to be quite tangible benefits from carving out Qt WebEngine to a separate item. Current thinking it that as a separate item we should be able to release Qt WebEngine every three months, following nicely the schedule of Chromium releases every six weeks. For Qt 5.12 LTS users this would mean the possibility to get not only the security updates, but a full new Chromium version supported on top of the long-term-supported release of Qt.

A big new thing we aim to release during 2018 is Qt for Python, i.e. bindings to Python programming language. Initially started as PySide, the work has continued for quite some time already. After a lot of work, we are reaching the point of being able to offer a technology preview to be used on top of Qt 5.11. For those not familiar with what Qt for Python is, it offers a set of bindings to enable Python applications to leverage Qt functionality. For example, Qt is a great framework to create the user interface of a Python application. Python is a powerful programming language with a large and growing user base. According to Stack Overflow, Python is the fastest growing programming language. Based on their analysis, the amount of Python developers exceeded the amount of C++ developers in 2012 and is currently over three times larger. Tiobe index ranks C++ to be still more popular than Python, but also based on their study Python is on a growth trajectory. Our hope is that many of the Python developers will find Qt valuable to use in their applications.

To complete the list of Qt framework items, let’s talk a bit about our ongoing research of Qt for WebAssembly. We have earlier looked into Qt for Native Client and emscripten and the current work for WebAssembly continues along the same path. Since 2017 the four leading browsers (Chrome, Edge, Firefox, and WebKit / Safari) have agreed upon the use of WebAssembly, so it is reaching to be a stable platform to run Qt on. We will blog more about running Qt applications on WebAssembly later, for now you can take a look at the code and build instructions.

Improved and new tooling for Qt development

In the tooling area, we have been working hard to create the new Qt 3D Studio based on the NVIDIA contribution we received a year ago. Qt 3D Studio is a great tool for creating interactive 3D user interfaces and applications. The editor is a cross-platform Qt application running on Windows, Mac, and Linux. Qt 3D Studio is not a tool for designing 3D models, these can be imported from commonly used tools such as AutoDesk Maya, MODO by the Foundry and even Adobe Photoshop, to mention some examples. Qt 3D Studio comes with a large set of materials and other assets to complement the models imported from other tools. The big thing for 2018 is the Qt 3D Studio 2.0 release where we switch the runtime to be based on Qt 3D. This allows deeper integration with other Qt functionality, improved portability, reduced maintenance effort and many other benefits.

While many of our Qt 3D Studio examples are geared towards Automotive and Digital Cockpit use cases, it is by far not just a tool for Automotive. Need for 3D user interfaces exists in multiple other industries such and automation, medical, entertainment, home appliances and more. Qt 3D and Qt 3D Studio are also fit for the creation of AR and VR applications – a raising technology area that has many benefits both for consumer and business needs. Automotive is an important area for Qt and we continue to develop Qt 3D Studio according to the needs of it, but not as the only industry to cater for.

In Qt 3D Studio 2.0 as well as the 2.x releases later in 2018 we focus especially into interoperability with other parts of Qt, for example, seamless integration with Qt Quick as well as improved integration with Qt Creator IDE. One of the upcoming key improvements in the editor is completely rewritten timeline component, providing greatly improved ergonomics and workflow. With 2.0 we also aim to provide the final and fully supported Behavior API and Data Node API. We also continue to improve examples and documentation in order to make the creation of 3D user interfaces with Qt efficient, easy and fun.

In addition to tooling for 3D UI creation, we are looking into ways to improve our tooling for 2D UI creation. In many cases, Qt Quick is all that is needed for the UI as it allows efficient creation of dynamic and interactive user interfaces. One of the areas we aim to improve is better support for importing assets from commonly used design tools. This has been possible before, but we want to make it better and easier also for people who are not experts in software development. Other key improvement areas include the functionality, ergonomics, and usability of the tooling – again also for people other than developers. The third key area to improve is the possibility to easily see the outcome of design changes in the target application, even in the target device. Ease of deployment to target device has always been a strong point of Qt Creator, but there is still room to improve. We are planning to have the improved 2D UI design offering ready for the first release during the latter part of 2018 – and will certainly provide more information of this during the year.

For Qt Creator, we have many incremental improvements planned to be done in the upcoming releases during 2018. Some of the main areas we are looking into are leveraging Clang code model, Python support, support for upcoming Qt target platforms (e.g. Qt for WebAssemby) and improved CMake support. Using Clang provides us with code-assistant functionality for modern (and future) C++ language standards. With Qt for Python, it is essential to offer Python support in Qt Creator, to allow convenient development and debugging of Python applications.

In addition to the high-profile features listed above, we continue to improve all the important areas of Qt Creator. For example, debugger support, code editor features (complementary to clang/qml code models) and releasing (improvements to the installation process, pre-releases via the online installer). Continuously improving CMake support in Qt Creator is needed to keep the growing CMake-using customer base satisfied. We also continue the development of QBS and maintenance of qmake, keeping also these as viable options for Qt applications. Just like with Qt in general, we are also continuously looking into the performance of Qt Creator and doing performance improvements.

A completely new component coming in 2018 is Qt Safe Renderer 1.0, which allows the creation of safety critical user interfaces much easier than before. It consists of two key items: integration to Qt Creator for the creation of safety critical user interface, and the renderer component for rendering the safety critical user interface. We are in the final steps to receive functional safety certification for the Qt Safe Renderer, including both the safety critical tooling and runtime parts.

Automation, Automotive, and other industries

In addition to improving the generic product offering according to feedback from customers and focused industries, we also have some items developed especially for the needs of certain industries. These are available for any industry but expected to be most relevant for the one they are named after. Prime examples of these are Qt for Automation and Qt Automotive Suite.

To learn more about Qt for Automation, check the blog post introducing it. The main items we have been cooking for 2018 are fully supported MQTT, KNX and OPC/UA implementations. Qt Mqtt and Qt Knx technology preview have been available since last year and both will be fully supported with the upcoming releases of Qt. Qt OpcUa is a new item, which we aim to first provide as a technology preview with Qt 5.11 and then finalize it for use with Qt 5.12 based on the feedback.

Qt Automotive Suite, available since 2016 is reaching 2.0 version soon. Based on Qt 5.9 LTS, Qt Automotive Suite 2.0 is a combination of automotive specific functionality from The Qt Company and our partners KDAB and Luxoft. Version 2.0 bundles with the Qt Safe Renderer, Qt 3D Studio, and includes an overhaul of QtIVI with the ability to generate APIs from an QFace IDL, improvements and added features to the Neptune UI, Application Manager and the GammaRay runtime introspector.

Get involved

If you want to learn more about upcoming things for Qt, please stay tuned for new blog posts and webinars about the upcoming features, contact our sales teams or join the discussion in the Qt mailing lists and developer forums. We are always delighted to see new contributors in the Qt Project as well as feedback to the pre-releases of Qt via bugreports.

 

The post Qt Roadmap for 2018 appeared first on Qt Blog.

Release 2.15.1: New Firebase Features and New Live Code Reloading Apps | Upgrade to Qt 5.10.1 & Qt Creator 4.5.1

V-Play 2.15.1 adds support for Qt 5.10.1 and the latest Qt Creator 4.5.1. Qt 5.10.1 comes with over 300 fixes and improvements. Qt Creator 4.5.1 adds several fixes as well. This update also improves the V-Play Firebase components with easier configuration and callback functions.

V-Play 2.15.1 Improvements

V-Play is now compatible with Qt 5.10.1 and Qt Creator 4.5.1. See later parts of this post for the highlights. V-Play Release 2.15.1 also includes many engine improvements:

New Live Code Reloading Apps for Desktop, Android and iOS

V-Play 2.15.1 comes with an improved V-Play Live Client and Server. The updated Live Client supports all new features and components.

v-play-live-code-change-reload-windows-android-ios

Reworked UI for Live Reloading Android and iOS Apps

There’s also a new V-Play Live version available for you on Android and iOS. The UI received a complete rework.

live-client-app-ios-new-ui

Project Cache to Open Recent Projects

It includes a new project cache, that lets you view your recent projects. This allows you to open your projects on your mobile phone also when not connected to your desktop, to show it to friends, customers or to yourself.

live-client-app-ios-project-cache

Run Code Examples from Documentation and Blog with the V-Play Web Editor

The new live client app also improves using the V-Play Web Editor. With the V-Play Web Editor, you can run code examples on your Android or iOS phone, right from your desktop browser. It’s a Cloud IDE for editing, running and debugging QML Code. Here is an example that you can try right away:

import VPlayApps 1.0
import VPlay 2.0
import QtQuick 2.8

App {
  NavigationStack {
    Page {
      title: "My First App"

      AppButton {
        anchors.centerIn: parent
        text: "Celebrate"
        onClicked: {
          nativeUtils.displayAlertDialog("Yay", "That is so cool!")
        }
      }
    }
  }
}

You can read more about this feature in this blog post.

Download the Latest Apps for Android and iOS

The new apps include all the latest V-Play features, so make sure to get the updated app to be fully compatible with current version of V-Play Engine and the Live Server. You can download the app for iOS and Android here:

Google_Play_Badge-1App Store
ic_launcherV-Play & QML Live Scripting App
Search in App Stores for: “V-Play Live Scripting”

Use WebView with Live Reloading on Android and iOS

The new V-Play Live Client mobile apps support the QtWebView module. You can now use code reloading also for apps that include a WebView.

import VPlayApps 1.0
import QtWebView 1.1

App {
  id: app

  NavigationStack {

    Page {
      id: page
      title: "WebView"

      WebView {
        anchors.fill: parent
        url: "https://www.google.com"
      }
    }
  }
}

Note that the WebView module is not available on Windows desktop.

Test Firebase and Facebook Plugins with Live Reloading

With the new V-Play Live Client apps, you can test the Firebase and Facebook plugins, without any integration steps. Note that both plugins connect to public test accounts, so make sure not to store any sensitive data.

import VPlayApps 1.0
import VPlayPlugins 1.0

App {
  id: app

  NavigationStack {

    Page {
      id: page
      title: "Firebase Database"

      FirebaseDatabase {
        id: database
        onReadCompleted: {
          if(key == "teststring") button.text = value
        }
      }

      AppButton {
        id: button
        anchors.centerIn: parent
        text: "Read Value"
        onClicked: {
          // get value from database. the result is processed in onReadCompleted of FirebaseDatabase
          database.getValue("public/teststring")
        }
      }
    }
  }
}

Firebase Callback Functions

When reading and writing data to and from a FirebaseDatabase, you can now use callback functions in addition to the item’s signals FirebaseDatabase::readCompleted() and FirebaseDatabase::writeCompleted().

You can supply a function as third parameter to the methods FirebaseDatabase::getValue(), FirebaseDatabase::getUserValue(), FirebaseDatabase::setValue() and FirebaseDatabase::setUserValue(). Both the signal and the callback function will be called on completion.

This is the same example as above, using a callback function instead of the readCompleted signal:

import VPlayApps 1.0
import VPlayPlugins 1.0

App {
  id: app

  NavigationStack {

    Page {
      id: page
      title: "Firebase Database"

      FirebaseDatabase {
        id: database
      }

      AppButton {
        id: button
        anchors.centerIn: parent
        text: "Read Value"
        onClicked: {
          // get value from database. the result is processed in callback function 
          database.getValue("public/teststring", {}, function(success, key, value) {
            button.text = value
          })
        }
      }
    }
  }
}

Firebase Configuration from QML

It is now possible to specify your Firebase Plugin account configuration in QML code. You can override the default configuration of FirebaseDatabase and FirebaseAuth using the new type FirebaseConfig. This allows for using multiple Firebase accounts from within the same app. It also simplifies the Firebase configuration for you in general, because you do not need any google-services file, but can configure your Firebase app completely from QML instead.

import VPlayApps 1.0
import VPlayPlugins 1.0

App {
  id: app

  NavigationStack {

    Page {
      id: page
      title: "Firebase Database"

      FirebaseConfig {
        id: customConfig
        projectId: "v-play-live-client-test-db"
        databaseUrl: "https://v-play-live-client-test-db.firebaseio.com"
        apiKey: "AIzaSyCheT6ZNFI4mUwfrPRB098a08dVzlhZNME"
        applicationId: "1:40083798422:ios:ed7cffdd1548a7fa"
      }

      FirebaseDatabase {
        id: database
        // assign custom config values. overrides config from google-services.json / GoogleService-info.plist
        config: customConfig
      }

      AppButton {
        id: button
        anchors.centerIn: parent
        text: "Read Value"
        onClicked: {
          // get value from database. the result is processed in callback function 
          database.getValue("public/teststring", {}, function(success, key, value) {
            button.text = value
          })
        }
      }
    }
  }
}

Native DatePicker Dialog for Android, iOS and Desktop

You can now let the user select a date from a native date picker dialog with the new function NativeUtils::displayDatePicker().

datepicker-ios-android

import VPlay 2.0
import VPlayApps 1.0
import QtQuick 2.9

App {
  id: app

  NavigationStack {

    Page {
      id: page
      title: "Date Picker"

      AppButton {
        id: button
        anchors.centerIn: parent
        text: "Display Date Picker"
        onClicked: {
          nativeUtils.displayDatePicker()
        }
      }

      Connections {
        target: nativeUtils
        onDatePickerFinished: {
          if(accepted) button.text = date.toLocaleDateString()
        }
      }
    }
  }
}

Fix QML Import Issue in Qt Creator

After the last V-Play update with Qt Creator 4.5, some of you faced issues with import statements in QML. This did not affect building and running the application. Yet it caused error messages in Qt Creator and affected auto-completion and syntax highlighting.

With V-Play 2.15.1, this is now fixed.

More Improvements and Fixes

  • Improve rebound effect of list view in drawer used in Navigation (default on Android or if using navigationModeDrawer).
  • Improvements for VPlayMultiplayer matchmaking and error handling. Update to latest Photon version for multiplayer services.
  • Increased timeout between plugin trial notice dialogs.
  • Reduce duration of V-Play Splash screen during development for standard build & run from Qt Creator.
  • Documentation improvements in various components. (Special thanks to user Marcin for extensive contribution!)
  • Disable user location updates for AppMap if AppMap::showUserPosition and AppMap::enableUserPosition is false, to optimize battery usage on mobile devices.
  • Fixes an issue where games would be always started in fullscreen mode while developing, if previously an app was run in iOS theme.
  • Fix App::isOnline and GameWindow::isOnline property on macOS Sierra and iOS 10.
  • Fix user position and location circle for AppMap with MapBoxGL plugin.

For an overview of all changes, make sure to see the changelog here.

Qt 5.10.1 Improvements for App and Game Development

Bugfix Release

Qt 5.10.1 comes mainly as a bugfix release. It contains over 300 fixes and improvements, with close to 1400 changes over 5.10.0.

Fix iOS Font Rendering Issue

One major fix targets the font rendering issue on iOS. This issue caused texts with native font to appear in weird glyphs occasionally. With this update, fonts on iOS appear as beautiful as they are, all the time!

Qt Creator 4.5.1 Support

The new version fixes several issues and brings improvements to the Qt Creator UI. It fixes crashes when importing or switching projects, as well as the mouse cursor getting stuck in waiting state on Windows.

How to Update V-Play

Test out all 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 complete list of the changes to V-Play with this update, please check out our change log!

 

 

More Posts Like This

how-to-test-online-code-examples-on-android-and-ios-with-live-code-reloading
Web Editor: Test Online Code Examples on Android and iOS with Live Code Reloading
v-play-2-14-2-how-to-use-vplay-plugins-with-live-reloading

Release 2.14.2: Live Code Reloading with Native Cross-Platform Plugins

v-play-live-reloading-windows-mac-linux-ios-android-qt
Release 2.14.0: Live Code Reloading for Desktop, iOS & Android

The post Release 2.15.1: New Firebase Features and New Live Code Reloading Apps | Upgrade to Qt 5.10.1 & Qt Creator 4.5.1 appeared first on V-Play Engine.

KDAB’s City Lights Display with Qt 3D

https://youtu.be/swP3GWd1Zzc?rel=0&showinfo=0

The City Lights demo is an example of Qt 3D being put to novel use to implement a deferred rendering pipeline.

With OpenGL, the number of lights you can show on a screen, also affecting objects in a scene, is limited by the need to use a forward renderer. Using Qt 3D, the geometry considerations can be separated out from the lighting ones, which massively reduces the complexity. This enables the scene in this demo to run on fairly mediocre hardware at 60 frames a second, even though it contains approximately 1500 real time lights.

KDAB Director, Dr Sean Harmer, maintainer of the Qt 3D project, explains.

 

  continue reading

The post KDAB’s City Lights Display with Qt 3D appeared first on KDAB.

Exporting 3D content for Qt 3D with Blender

At the heart of every 3D application is geometry. Qt 3D-based 3D applications are no different and require the user to either generate geometry or provide asset files for Qt 3D to load. This blog post demonstrates how Blender and its Python API could be used to write an exporter that generates geometry for Qt 3D.

For those of you not yet too familiar with Qt 3D, let me remind you that Qt 3D is based on an Entity Component System.
A given Entity gets its behavior defined by the various components it aggregates.

Assuming you want to render some 3D content, a renderable entity would be composed like so:

[sourcecode lang="cpp"]
Entity {
components: [
GeometryRenderer {
geometry: ...
},
Material {}
]
}
[/sourcecode]

 

Loading Geometries with Qt 3D

There are currently 3 ways to incorporate geometry in a Qt 3D application:

Using the default meshes provided by Qt 3D Extras

QConeMesh, QCuboidMesh, QCylinderMesh, QPlaneMesh, QSphereMesh, QTorusMesh

These are all QGeometryRenderer subclasses which take care of generating geometry based on configurable properties. It's up to you to provide a Material that will shade your geometry.

[sourcecode lang="javascript"]
Entity {
components: [
ConeMesh {
rings: 16
slices: 16
topRadius: 0.1
bottomRadius: 1.0
},
Material {...}
]
}
[/sourcecode]

 

Using QMesh component to load a geometry file

Several backend plugins are available for .obj, .fbx and gltf version 1. The list of plugins will likely grow in the future (work on a gltf version 2 importer is currently ongoing). QMesh is also a QGeometryRenderer subclass, you also need to provide a Material.

[code language="javascript"]
Entity {
components: [
Mesh {
source: "path/to/my/file.obj"
},
Material {...}
]
}
[/code]

 

Using QSceneLoader component to load a scene file

QSceneLoader is also plugin based. At the time of writing, one such plugin is based on the Open Asset Importer Library (Assimp) which supports the following formats.

There's also another plugin which supports gltf version 1.

[code language="javascript"]
Entity {
components: [
SceneLoader {
source: "path/to/my/scene.obj"
}
]
}
[/code]

The subtelty between QMesh and QSceneLoader is that QMesh loads only a single mesh whereas QSceneLoader will load an entire scene. Essentially QSceneLoader will generate a subtree of QEntity with QGeometryRenderer and QMaterial components. The nice thing is that QSceneLoader will also instantiate matching Materials to go with each mesh.

In most cases you'll either use QSceneLoader to load a rather complex scene or, if you know how the scene content is structured, decide yourself on which parts you need and use several QMesh components.

Issues

Now this is all fine but you'll often end up with one of these issues:

  • Geometry is generated at run-time which can be costly
  • Many 3D formats are text-based (takes up space on disk, slow parsing at run time)
  • Loading a scene subtree requires traversing said subtree to retrieve entities composed of components of interest
  • QSceneLoader may duplicate materials, effects, attributes depending on the scene file
  • Declaring several QEntity with QMesh components can be tedious
  • Import plugins for QMesh/QSceneLoader are not available on all platforms and may not cover all formats.

 

From a general perspective, the current mechanisms make it tedious for the developer to control a complex scene. They either completely hide away the structure of a loaded subtree or, on the contrary, force you to know exactly what composes your scene and let you do the heavy lifting of deciding which meshes you care about.

If you are after performance, you need to know how your scene is structured, which materials are in use and how large your geometries are. With this information you can decide if you need to:

  • rework you geometry to reduce the number of vertices to be drawn
  • group several parts together so that they can all be drawn at once
  • reduce the amount of materials required.

So what if instead of loading something blindly, we generated Qt 3D content in advance, as part of our tooling or asset conditioning work?

 

Blender

Blender is a free and opensource 3D creation suite. I wouldn't go as far as saying that it's intuitive to use for a newcomer, but it's a really powerful tool. In addition, it provides a powerful Python API which can be used to write importers, exporters or simply automate processes (importing and exporting geometries offline). The nice thing is that the API is documented, the bad thing is that the documentation is mostly a list of methods and members...

How could Blender solve any of the issues we have?

Instead of generating or loading geometry at runtime, I therefore decided I would try to experiment and write an exporter plugin for Blender.
The goal for it would be to generate the QML content for an application (though we could easily extend it to cover C++ as well) and export the geometry buffers to binary files that just need to be read at runtime without requiring any parsing.

This could solve the issues of slow startup caused by parsing text-based files and possibly duplicating effects and materials. This also solves the case of import plugins deployment (as we are now performing this offline) and only shipping binary files that can be read with the readBinaryFile functions on the QML Buffer element. Finally this also gives us the complete structure of our scene.

[sourcecode lang="javascript"]
Buffer {
type: Buffer.VertexBuffer
data: readBinaryFile("qrc:/assets/binaries/bufferdata.bin")
}
[/sourcecode]

 

Creating a Blender Exporter Addon

A blender addon can be easily created by subclassing bpy.types.Operator and optionally bpy_extras.io_utils.ExporterHelper which provides convenience helpers as well as a default UI layout.

Overview of an exporter class

  1. Define members from bpy.types.Operator and ExporterHelper
    • bl_idname
      • The addon will be accessible in the Blender API though bpy.ops.bl_idname
    • bl_label
      • The name used on the export button UI
    • filename_ext
      • The name of our format extension if we have one
  2. Set UI properties and export options
    • Blender provides default property types
    • In the Qt3DExporter cases, properties were added to control:
      • whether to export only the selected objects or the whole scene
      • whether to export only the visible objects in the scene
      • whether we want meshes to be grouped in a collection
      • whether we want materials to be grouped in a collection
      • whether we want to export a full Qt3D application or just the
  3. Implement the draw method to lay out our properties
    • Retrieve the operator's layout and add rows and columns
      • We can add labels and reference properties you have previously created
  4. Define the execute method which will be the entry point of our exporter

[sourcecode lang="python"]
class Qt3DExporter(bpy.types.Operator, ExportHelper, OrientationHelper):
"""Qt3D Exporter"""
bl_idname = "export_scene.qt3d_exporter";
bl_label = "Qt3DExporter";
filename_ext = ""

# We set up exporter UI here
use_mesh_modifiers = BoolProperty(
name="Apply Modifiers",
description="Apply modifiers (preview resolution)",
default=True,
)

use_selection_only = BoolProperty(
name="Selection Only",
description="Only export selected objects",
default=False,
)

def draw(self, context):
layout = self.layout
col = layout.box().column(align=True)
col.label("Nodes", icon="OBJECT_DATA")
col.prop(self, "use_selection_only")
col.prop(self, "use_visible_only")

def execute(self, context):
# Actual exporting work to be done here

def createBlenderMenu(self, context):
self.layout.operator(Qt3DExporter.bl_idname, text="Qt3D (.qml)")

# Register against Blender
def register():
bpy.utils.register_class(Qt3DExporter)
bpy.types.INFO_MT_file_export.append(createBlenderMenu)

def unregister():
bpy.utils.unregister_class(Qt3DExporter)
bpy.types.INFO_MT_file_export.remove(createBlenderMenu)

[/sourcecode]

Most of the work will be done in the execute method. When reaching that point you'll want to:

  1. check which options have been selected by the user
  2. retrieve the export path selected
  3. gather data from the blender scene
  4. perform any post processing or conversion
  5. write the exporter data in whichever format you're interested

 

Parsing Blender Data

Collections

We can do a lot of things with the Blender API, the hard part is really finding out what you need

In our particular case we only care (for a first version) about:

  • Objects (bpy.data.objects)
    • Collections of objects that reference a datablock
      • name
      • data (reference to a datablock)
      • type (type of datablock being referenced)
      • matrix_local
      • matrix_world
      • select (whether we are selected or not)
      • parent (reference to a parent object)
  • Meshes (bpy.data.meshes)
    • Collection of datablocks containing information about a mesh
      • name
      • material slots (references to materials used by the mesh)
      • uv_layers
      • vertex_colors
      • vertices (list of position)
      • edges (an edge references 2 vertices)
      • loops (collection of loops, a loop references a vertex and an edge)
      • polygons (a list of loops forming a polygon)
  • Materials (bpy.data.materials)
    • Collection of datablocks containing information about a materials
      • name
      • ambient
      • diffuse_color
      • specular_color
  • Modifiers (object.modifiers)
    • Collection of modifiers an object can reference
    • A modifier is a visual transformation applied to a mesh
      • Mirror
      • Array
      • Solidify
      • Subsurface...
    • An object referencing a Mesh datablock that has modifiers can be transformed into a Mesh with the modifiers applied by calling object.to_mesh()
  • Lamps (bpy.data.lamps)
    • Collection of datablocks containing information about lamps
      • type (POINT, SPOT, SUN)
      • color
      • intensity
      • SPOT
        • spot_size (cut off angle)
        • constant_coefficient (constant attenuation)
        • linear attenuation
        • quadation attenuation
      • POINT
        • constant_coefficient (constant attenuation)
        • linear attenuation
        • quadation attenuation
  • Scene (bpy.context.scene)
    • References objects and render settings for the scene

Now that we know what we care about, the next part is traversing these collections and converting them to Qt 3D content.

Meshes

First we need to go over all the meshes in the scene and gather information required to convert these to QGeometryRenderers, QGeometry, QAttributes and QBuffers.

The idea is to go over each Blender mesh and process then as follows:

  1. Triangulate
  2. Apply the modifiers it references
  3. Retrieve vertex data (position, normals, texture coordinates, colors)
    1. Write data into a binary file
    2. Record description of attributes
  4. Compute the indices
    1. For each material being referenced by the blender mesh
      1. Create a submesh (basically a QGeometryRenderer in Qt3D)
      2. For each polygon referenced by the submesh
        1. compute list of indices based on  the loops of the polygon
      3. generate and record the IndexAttribute for the submesh
    2. Generate the IndexBuffer based on the sub meshes
    3. Write data into a binary file.

We keep the data we have produced here for later.

Materials

Next, we need to gather information about each instance of Material of the scene to later on create and instantiate QMaterial subclasses.

For now the exporter is only recording the name, ambient, diffuse and specular color. Later on I'd like to extend that to either export a shader directly or switch to PBR materials.

Objects

Once we've created an intermediary representation for our mesh data and material data, we can proceed with the actual exporting of the scene.

The idea is to retrieve all the objects references by the BlenderScene. Then, from these objects, we can create a hierarchy.

Finally it's just a matter of traversing the tree.

For each object:

What type of object we are dealing with?

 

All of the above work has been implemented in a dedicated Exporter class. It is instantiated and called in the execute function of our addon which looks like below:

[sourcecode lang="python"]
def execute(self, context):
exportSettings = self.as_keywords()
exportSettings["global_matrix"] = axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up).to_4x4()

self.binaryDirectoryName = "assets/binaries/"
self.shadersDirectoryName = "assets/shaders/"
self.qmlDirectoryName = "qml"

self.userpath = self.properties.filepath
if not os.path.isdir(self.userpath):
self.userpath = os.path.dirname(self.userpath)
msg = "Selecting directory: " + self.userpath
self.report({"INFO"}, msg)

# switch to work dir and create directories
os.chdir(self.userpath)
if not os.path.exists(self.binaryDirectoryName):
os.makedirs(self.binaryDirectoryName)
if not os.path.exists(self.shadersDirectoryName):
os.makedirs(self.shadersDirectoryName)
if not os.path.exists(self.qmlDirectoryName):
os.makedirs(self.qmlDirectoryName)

# Save scene into scene
scene = bpy.context.scene

exporter = Exporter(scene, exportSettings)
exporter.export()

# Create QML Files
exporter.createQMLNodeTree()

# Create .qrc file
exporter.generateQRCFiles()

# Create main.cpp
exporter.generateMainCppFile()

# Create .pro
exporter.generateProjectFile(self.userpath)

[/sourcecode]

Does it work?

Well actually it does.

As a test sample I've used a mesh from blendswap

Where to get it?

Here. Usage instructions are provided on the repository. It should work with pretty much any blender scene. Just make sure you have assigned a material to the elements you want to export.

Next steps

  • Export Animations
  • Export Armatures
  • Better Material support
    • export textures
    • generate shader when possible
    • investigate if the QShaderProgramBuilder could be used to export node trees from blender
  • Use instancing for Array modifiers
  • C++ support

continue reading

The post Exporting 3D content for Qt 3D with Blender appeared first on KDAB.

Protecting a Qt Application or a Device Against Hacking, Part 2

by Sakari Himanen, Security Tech Lead at Intopalo Oy (Qt Blog)

Why would anyone want to hack an application or a device? And how would they go about their attack? And, most importantly, how can you protect your software against malicious attacks?

This post is a follow-up to part 1 of the topic. This time we take a fairly detailed look at attackers’ motivations, methods and the ways to deter most attacks from succeeding. This blog post is aimed primarily at anyone who have specific reverse engineering or tampering related risks in their systems, for example related to processing licenses, valuable content or media, proprietary algorithms or financial transactions.

Why would anyone want to hack my software?

“We’re not Facebook or handle ultra-sensitive data – why would anyone want to hack us?” It is easy to think that our application does not attract attackers to take the effort to reverse engineer the software.

However, there are several reasons why attackers might want to target any application. Here are the most common motivations.

Circumventing a licensing check

This is one of the most common targets. The attacker tries to disable the logic that checks for a valid license in order to be able to use the application without limitations. The usual way to achieve this is by modifying the application binary.

Extracting secret keys or passwords

Applications often contain embedded information which is used to encrypt the data stored in the application, enable protected communication for example with a cloud backend, or enable the application to use other resources that require authentication. By carefully analysing the application binary, it is easy to locate and extract the secret keys or passwords, if they are not protected.

Understanding how a proprietary algorithm works

Many applications contain implementations of algorithms that have intellectual property value. These may be developed by the company developing the application, or parts of the application that are licensed from other developers. If the algorithm code is not obfuscated in any way, the pseudo-code of the algorithm can be easily extracted from the application binary.

Finding open vulnerabilities that can be exploited to attack running systems

Many applications use third party modules (code, libraries, other assets) either directly or indirectly. Any such modules can have vulnerabilities. Further, updating such modules, especially in embedded applications, may not be straightforward. Obtaining knowledge of such vulnerabilities can be used to attack other systems that use the same modules.

Changing the application’s operation

Sometimes the attackers aim to change the behavior of the application, but only very slightly, so that the changed application is virtually not distinguishable from the original application. For example, consider an application used for financial transactions, used by consumers or businesses. If an attacker is able to distribute a slightly altered version that is able to manipulate a recipient’s bank account number, it is possible to gain significant monetary benefit in a short time before anyone notices the attack.

Changing the device operation or configuration

Physical devices depend more and more on the device software, such as firmware or special applications. Because of this, the configuration of devices is often done purely with software. For example, a high power variant of an engine may be just a locked configuration in the engine controller software. In this kind of scenario, the attacker aims to perform “feature unlock attack” by targeting to modify the controller software.

Making and distributing an application version that crashes or jams

Sometimes the attacker’s target is not to directly benefit from modifying the application. Instead, the target may be simply to cause harm to the services related to the application. For example, an application that crashes every time a certain operation is performed may cause significant monetary losses or bad reputation for the related services.

How attackers think – Popular hacking methods explained 

To protect your application against various kinds of attacks, it is useful to first think like an attacker. Try to think of the obvious ways to attack specifically against your application and the different motivations an attacker might have.

Even more importantly, think out of the box: what would be the unlikely but still possible attack against your application? Also, put yourself in different user roles and try to identify the ways to attack from the viewpoint of each responsibility actor of your application. The actors typically operate over trust boundaries and that may then reveal execution paths or data flow which initially do not seem likely or possible.

Static binary analysis

Probably the most common way to attack an application is static binary analysis. It is often easy to obtain the actual binary. Tools to analyse the binary are available either free or with a reasonable cost. Tools allow parsing and extracting the various parts of the binary with a single click. There is no need for the attacker to write custom code for every target platform or architecture.

A typical application binary contains multiple types of sections. They can be roughly categorized as sections containing code, sections containing static data such as strings and sections containing runtime data. Out of these, the code and static data sections are the most interesting for the static analysis context.

Static data sections, such as a string section, usually contain the data that can be considered as application assets. It is deceptively easy to think that data embedded as strings is protected from attackers. That is not the case. In the worst case, the string data may contain even passwords or application’s secrets in plain format. If they are un-encrypted or un-obfuscated, extracting the string values is as easy as reading a book.

The code section contains all of the application logic. Disassembler tools can easily resolve the pseudo code structure, call hierarchy, local and global variable references and other similar information. But even an average-sized application will contain lots of binary code. So, the aim of the attacker is not to resolve every line of code. Instead, the aim is to identify the relevant parts of code to be used as the target for the attack.

For example, a few hundred instructions containing a license check logic is an attractive target for an attack. It does not require very special knowledge to break the license check. At the very minimum, modifying one single instruction may be enough.

hopper_disassembler

 

Capture from Hopper disassembler tool demonstrating the control flow capabilities

Dynamic binary analysis

If an application is using the typical first level of protection, the code obfuscation, static binary analysis may not be enough to reveal the secrets. The typical next step is dynamic binary analysis. This means basically analysing the application operation in runtime: collecting all the possible data from code execution and memory usage and analysing the execution paths that can’t be revealed with static analysis.

There is a wide range of tools available for dynamic analysis. The free or low-cost tools provide the basic capability for disassembling and debugging an application. But there are also high-end tools, such as IDA Pro, which are built with loads of tools for analysing the target binaries.

A crucial element of dynamic binary analysis is to also understand the attack context. The typical attack context is so-called “whitebox attack context”. It means that the attacker has full access to the target application, to the application binary and to the execution environment. In practice this means that the attacker is able to control every aspect of application execution when trying to break it or steal its secrets.

Why is the attack context so important? Because it drives the assumptions what the developer can do about possible attacks and how they affect your application. Once again, it is easy to assume that “as my application is running in environment X, attack type Y is not applicable”. But very often, usually due to the resourcefulness of the attacker, the attack context ends up being the whitebox attack which means that the assumptions done in the design phase are the ones which eventually leave the application vulnerable. For example, developer may think that if an application is running in an embedded device, an attacker has no meaningful access to it. But in reality, attacker could gain access to device firmware, remove the software protection in the firmware, and then attack the application directly.

Another important concept is so-called “code lifting”. Code lifting refers to the scenario where the target application can be lifted for example to a simulator environment where the attacker has full capability to control the code execution or monitor the memory usage – even kernel memory. This is often paired with the white-box attack context. First the attacker gain access to the target application binary, and then moves it to another execution environment.

Methods to protect applications and devices against hacking

In the first blog post, we presented some basic methods for protection of your application, such as using static linking instead of dynamic linking, and making sure that the symbol stripping is enabled when generating the final application binary. But when there is a need for more comprehensive protection, there are additional methods for protecting applications against various kinds of attacks.

These methods can be roughly divided to four categories:

  • Obfuscation
  • Anti-tampering
  • Anti-debugging
  • Whitebox cryptography

Obfuscation

The purpose of code obfuscation is to mainly prevent static analysis. Typical ways to perform code obfuscation is adding obfuscation of the strings used in the application, encrypting the static data sections of the binary so that they are decrypted when the application starts, and adding artificial code structures or execution paths which cannot be resolved with static analysis.

An example of code obfuscation would be a case where a code block is paired with a parallel “copy block” and the execution of the two blocks is controlled with a conditional branch with specific characteristics. The branch logic should be deterministic so that the developer can trust that the code is executed correctly, but static analysis can’t deduce the runtime behavior.

Just like static analysis is the first way to perform an attack, it is also the first level of defense. For example, a high-quality disassembler may be able to see partially through the obfuscation patterns. Also, the quality of modern compilers poses a problem. Fake code blocks may be wiped away by code optimization and hence decrease the quality of obfuscation.

Anti-tampering

The purpose of anti-tampering is to protect the application against dynamic analysis. While there are various approaches on how to implement anti-tampering, the basic idea is that the original application binary is modified to include additional code that does runtime checking of the binary. Such code snippets monitor specific areas of the binary to check if the area is modified and perform counteraction if a modification is detected.

Applying anti-tampering is very much application and execution environment specific. For example, there is a tradeoff between how much code modification checks can be used vs. the performance of the application. Also, the target architecture plays a major role: an approach that works well in certain environment may not protect the application in a different environment.

This also means that adding anti-tamper protection is much more tedious that adding basic code obfuscation. While code obfuscation can be usually applied at the compiler frontend level, anti-tampering has a dependency to compiler backend and architecture-specific parts.

Anti-debugging

The purpose of anti-debugging is simply trying to prevent the attacker from performing code lifting and running the application in a simulator or a similar environment with a debugger. Being able to use a debugger is often a big aid for the attacker as it enables the attacker to stop code execution and monitor the application memory space and registers at any point of time.

The usual approach for implementing anti-debugging is trying to detect the debugger process and preventing it from hooking the target application. The big challenge is that the attacker may try to attach the debugger at any point of application execution. It is not enough to only perform such check when the application is starting, for example. Resolving this challenge is not trivial. Detailed knowledge about the debugger behavior is required, and the anti-debugging logic must be built to protect from all possible ways to utilize the debugger.

Whitebox cryptography

Whereas code or string obfuscation tries to obfuscate the static application data, it does not distinguish security critical data from other static data. Hence, any application containing data such as cryptographic keys needs to have a solution for protecting these critical assets. It may prove to be very difficult to protect the keys only, but there is an alternative solution: whitebox cryptography.

The target of whitebox cryptography is to be able to protect the cryptographic keys even in an environment subjected to a whitebox type of an attack. The usual approach to implement whitebox cryptography is to integrate the key for a cryptographic algorithm as part of the algorithm implementation itself. That means, the key becomes an inseparable part of the algorithm implementation.

The benefit here is that instead of using the cryptographic key in an application, it is possible to use whitebox implementation of the algorithm directly, and no keys are exposed to the attacker.  For example, one of the most commonly used cryptographic algorithms is AES algorithm. It has been a target for wide academic research from whitebox cryptography perspective, and it is also an essential algorithm to have in the product feature set for whitebox cryptography vendors.

Example case: INSIDE Secure tools
INSIDE Secure is an example of a state-of-the-art code protection tool vendor. Their Code Protection toolset can be run on a Qt application to both obfuscate the binary and static data including string, and make the Qt application self-protecting against tampering, irrespective of the integrity of the environment.

This makes it very hard to circumvent licensing checks, find out sensitive IPR, or breach the application integrity when processing financially valuable transactions.

Summary

A successful protection of an application is always a sum of its parts. As a developer, if you neglect one area, you will leave your application vulnerable to certain kind of attacks. Consequently, serious application protection is something that a normal developer should not try to implement by himself. There are a number of high quality tools available for just this purpose. Just go and pick the right one for you – and remember that a commercial license of Qt allows using these means of protecting your application or a device.

Can we help you?

Intopalo is a Qt Service Partner that specializes in software security. If you are not sure where to start, we are more than happy to give you a hand and guide you to the right direction. Visit Intopalo website for more information.

The post Protecting a Qt Application or a Device Against Hacking, Part 2 appeared first on Qt Blog.

Qt 5.11 Brings New Accessibility Backend on Windows

Accessibility technology encompasses assistive tools such as screen readers, magnifiers and braille displays, as well as APIs and frameworks that allow applications to expose elements of their UI to such tools.

While some UI widgets provided by the operating system may already be prepared to provide content and metadata to assistive tools, Qt renders UI elements itself. This approach requires a way to expose information about these elements to accessibility frameworks, which would otherwise perceive the applications as sets of empty windows.

To expose information about UI elements on Windows, Qt relied on the legacy Microsoft Active Accessibility framework (MSAA), until Qt 5.10. However, proper framework support was lacking in some areas, and nowadays MSAA has been superseded by a new framework and its use is no longer recommended for new applications.

With release 5.11 we will replace the MSAA accessibility backend with a new implementation based on the more modern Microsoft UI Automation, which superseded MSAA as the de facto standard for accessibility on the Windows platform. UI Automation has been available in all Windows releases since RTM versions of Windows 7 and Server 2008, as well as provided with system updates on Windows XP, Vista and Server 2003.

Since the accessibility changes in Qt 5.11 are internal, existing accessible applications are not expected to require any changes to utilize the improved functionality provided by UI Automation. Compatibility with MSAA-only assistive tools is maintained by bridge components built in the UI Automation framework itself.

One area where immediate improvement resulting from the new approach can be perceived is in the control of Qt-based applications using the built-in virtual keyboard in touchscreen-based Windows computers, like the Microsoft Surface line. In Qt 5.10, compatibility with some UI widgets was limited and events like the automatic showing and hiding of the virtual keyboard were not supported. With Qt 5.11, the same level of functionality available to applications based on native Windows widgets should be expected.

Also, the new UI Automation support in Qt may become useful for application testing, since it can provide metadata and programmatic control of UI elements, which can be leveraged by automated test suites and other tools.

We invite users to test the new accessibility functionality, and to give us feedback by writing to the mailing lists and reporting bugs.

 

The post Qt 5.11 Brings New Accessibility Backend on Windows appeared first on Qt Blog.

Qt 5.11 Alpha Released

Qt 5.11 Alpha is released today. As usual the official Alpha is a source code delivery only, but later we will offer development snapshots of Qt 5.11 regularly via the online installer.

Please check Qt 5.11 New Features wiki to see what new is coming with Qt 5.11 release. Please note that the feature list is still in progress and not to be considered final before the first Beta release.

Next milestone in our way to final Qt 5.11 release (which is planned to happen in May) will be first Beta release. We are targeting to get it out as soon as possible soon after the Alpha. We will release several Beta releases in similar manner as before, available via the online installer.

Please download the Qt 5.11 Alpha source packages from your Qt Account or from download.qt.io.

Most importantly, remember to give us feedback by writing to the mailing lists and reporting bugs.

The post Qt 5.11 Alpha Released appeared first on Qt Blog.

Qt in Visual Studio: Improving Performance

In the last post, we discussed a new approach to design time and build time integration of external tools in Visual Studio using MSBuild rules and targets. This will be included in the upcoming release of version 2.2 of the Qt VS Tools. In this post, we will discuss the performance improvements that are also included in this new version.

We’ll focus on two situations where users of the current version (2.1) of the Qt VS Tools have reported sub-standard performance:

  • Adding new header files, especially to projects with many configurations
  • Converting Qt projects (.pro files) with many files

We’ll look at the scale of these problems and why they occur, then discuss the steps that have been taken to fix the problems and the improvements that have been achieved.

Adding Header Files to a Project

To understand the scale of this problem and the effectiveness of our solution, we ran the same set of tests using both the current and the new version. These tests consisted of adding several header files containing Qt macros to projects with varying numbers of configurations. For more information on the test setup and a detailed analysis of the results, please refer to the section “Measuring Performance”, at the end of this post.

Looking into the results of testing version 2.1, we found that the time to add files to a project got progressively worse, up to several minutes, the more configurations were defined in the projects. The worst case scenario was just under 45 minutes for adding 10 files to a project with 20 configurations. It was possible to determine that the performance degradation is closely related to the approach previously followed, where files generated by moc were explicitly added to the project in order to be included in the C++ compilation. The time spent modifying properties of generated files accounted for 98% of total time.

As we discussed in the previous post, the new approach based on MSBuild rules and targets allows source files to be added to the build process while it is ongoing. This way, instead of adding the files generated by moc as static project items, they are added dynamically to the C++ compilation during the processing of the moc target. This should represent a significant improvement to the cost of adding new header files to a project. The test results from version 2.2 show that this is indeed the case: the time spent on each test case was, on average, 95% less than that of version 2.1, and what was previously the worst case scenario (10 files added to a project with 20 configurations) now took only 3,2 seconds to complete.

This improvement in performance is not limited to the action of adding header files to projects. It will have an impact in all operations that handle generated files as project items. The following is a list of other use cases that should also benefit from the increase in performance (especially in projects with several configurations):

  • Importing Qt projects (see next section);
  • Creating new Qt classes;
  • Manually adding/removing the Q_OBJECT macro in a file;
  • Changing the Qt version;
  • Changing the path to the moc, rcc and uic generated files.

Importing Qt Projects

The problem described above also applies when importing a .pro file, since properties of generated files are also accessed and modified during import; in fact, the import procedure modifies properties of all project files. To avoid this problem, in the new version of the Qt VS Tools, the Visual Studio project that is generated by qmake is not immediately loaded into Visual Studio; all modifications are carried out as an XML transformation on the project file. Only then is it loaded into Visual Studio. This way we avoid any project-wide processing while the project is loaded.

To test this optimization, we imported the Qt example project demobrowser. Below is a recording of this test using version 2.1 (left) and version 2.2 (right) of the Qt VS Tools (the recording also includes building and running the program). We found that the time to import the project decreased from over 30 seconds in the current version to less than 6 seconds in the new version.

Importing demobrowser

 

Measuring Performance

To measure the scale of the performance problem when adding new header files, we ran a series of tests with an instrumented build of the Qt VS Tools that recorded the number and duration of calls to every function. As the performance seemed to be influenced by the number of project configurations, we tested with several projects containing respectively 2, 5, 10, 20 and 40 configurations. As the number of files added also seemed to be a factor, we tested each project with 5, 10, 20 and 40 files added, for a total of 20 test cases. We will use the variable C to represent the number of configurations, and the variable F to represent the number of files added.

The results of testing with version 2.1 of the Qt VS Tools show that the performance degrades significantly as we increase the number of configurations and the number of files added. The graph below summarizes the test results. Some tests were interrupted after 45 minutes; this is noted in the graph by grayed-out bars. The blue bar on the left serves as a 1 minute scale.

Test Results v2.1

Looking further into the test data, we find that most of the elapsed time was spent calling functions of the Visual Studio SDK. For example, in the test case C=20,F=10, which took almost 45 minutes to complete, 98% of that time was spent in the following calls:

Calls to Visual Studio SDK

These functions were called while adding generated files to the project – files generated by moc must be added to the project in order to be included in the C++ compilation. For every header file added, one generated file per configuration will also be added to the project, i.e. F×C generated files. In the test case of C=20,F=10, this accounts for the 200 calls, e.g. to the AddFile function.

Each one of the F×C generated files can only be compiled if the corresponding project configuration is active. For all other configurations, the file must be set to “excluded from build”. This is the reason for the larger number of calls to the set_ExcludedFromBuild function, i.e. F×C×(C-1) calls to that function. In the example of the C=20,F=10 test case, this accounts for the 3800 calls to set_ExcludedFromBuild.

We’ve also found that the functions of the Visual Studio SDK tend to become slower as the number of calls increases. In the case of set_ExcludedFromBuild, we see that the average time per call went from 11 milliseconds, when calling the function 10 times, to 535 milliseconds per call for 3800 calls:

Calls to set_ExcludedFromBuild

With the approach followed in version 2.1, which requires that generated files be added to the project, there doesn’t seem to be much room for improvement in performance: almost all time is spent inside external functions and these functions are called exactly the number of times needed. The problem of the performance degradation seems then directly linked to the approach itself.

To test the performance of the new approach, we ran the same 20 test cases using the new version 2.2 of the Qt VS Tools, which uses the Qt/MSBuild targets; the results are shown in the graph below. As before, the blue bar on the left represents the same 1 minute scale.

Test Results v2.2

Comparing the results of both tests, in version 2.2 the time spent was, on average, 95% less than that of version 2.1. The average cost of adding header files to a project, per file and configuration (i.e. total time divided by F×C), decreased from 300 milliseconds to 40 milliseconds.

The post Qt in Visual Studio: Improving Performance appeared first on Qt Blog.

Cutelyst on TechEmpower benchmarks round 15

On Valentines day TechEmpower released the results of fifth round of it's benchmarks tests on web frameworks, it took almost a year since round 14 and I really hope round 16 comes out sooner.

Since this round took a long time and was scheduled to be release many times last year I decided not to update Cutelyst to avoid not having the chance to fix any issues and have broken results. Cutelyst 1.9.0 and Qt 5.9 were used, both had some performance improvements compared to round 14, and thus you can see better results on this round compared to 14, most notably the JSON tests went from 480k request/second to 611k req/s, also due this Cutelyst release used jemalloc was again not used due a bug we had in CMake files that didn't link against it.

In this round some  other frameworks have also done their optimizations and a few managed to do better than Cutelyst, even though we were faster in all tests compared to the last round. It might be even related to some OS tuning as most results seemed to went up a bit, however if you put the filter on "FullStack" frameworks Cutelyst is leading in most tests.

TreeFrog framework had results in TechEmpower long before I wrote the tests for Cutelyst, but due errors on TreeFrog tests on last rounds this was the first round where you can compare the results of two Qt Web Frameworks.

For the next round I expect the results to be even better now that we will properly use jemalloc, and our epoll dispatcher got a better implementation, I also plan to use Cutelyst 2 and try increasing some buffers as the servers have plenty of RAM that I didn't care on using.

If you want to know more about Cutelyst visit https://cutelyst.org/ and give us a Star on GitHub (we are now past 300!!) https://github.com/cutelyst/cutelyst

Web Editor: Test Online Code Examples on Android and iOS with Live Code Reloading

Did you ever wonder how to quickly test online code examples? Did you ever see a code example and thought “I would love to try that right away”?

V-Play got you covered! With the V-Play Web Editor, you can run code examples on your Android or iOS phone, right from your desktop browser. It’s a Cloud IDE for editing, running and debugging QML Code. You don’t need to install any native SDKs or development environment like Qt Creator on your computer. You don’t even need to install the V-Play SDK or Qt SDK. All you need is to download the V-Play Live Scripting app for Android or iOS.

1. Download the V-Play Live Scripting App

The V-Play Live Scripting app is available on Android and iOS. Download it to use Live Code Reloading from your browser or desktop.

Google_Play_Badge-1App Store
ic_launcherV-Play & QML Live Scripting App
Search in App Stores for: “V-Play Live Scripting”

2. Run Code Examples from Documentation and Blog with the V-Play Web Editor

You can find the V-Play Web Editor for Qml code at https://v-play.net/web-editor/.

web-ui

For convenience you can also find a button above all code examples in our documentation and on the blog. Click on it to open the example in the Web Editor. Here is an example that you can try right away (make sure you read this post on your desktop!):

import VPlayApps 1.0
import VPlay 2.0
import QtQuick 2.8

App {
  NavigationStack {
    Page {
      title: "My First App"

      AppButton {
        anchors.centerIn: parent
        text: "Celebrate"
        onClicked: {
          nativeUtils.displayAlertDialog("Yay", "That is so cool!")
        }
      }
    }
  }
}

There are some more cool examples at the end of this post, make sure to give them a try!

3. Test on Android and iOS at the Same Time

You can connect all your mobile phones to the Web Editor at the same time. This means you can test how an example looks on different platforms simultaneously.

The Web Editor also displays log output of your connected devices.

 

web-ui-clients

4. Live Code Reloading in your Browser

You would like to change the example code a bit? No problem!

You can edit the code in the Web Editor and click the run button, or hit CTRL+S (CMD+S on macOS). The code reloads on your mobile phone immediately and shows the new result.

It is also possible to write your own code, or copy/paste any example to the Web Editor. You get the full log output of any connected mobile phone, to find possible errors in your code.

Cloud IDE Benefits for You

The biggest benefit was already highlighted in the introduction of this post. You can test code examples right away on your mobile phone from the browser. This works without installing any SDK on your desktop.

Besides that, it is also useful for developers that already have everything installed. You save the effort to create a new project to test an example. You can explore the documentation and test any interesting example with only a button click.

With Live Code Reloading, you can tweak the example within your browser until it fits for you.

Live Code Reloading on Desktop, Android and iOS

You can also use the V-Play Live Scripting app for development on desktop. You can find more info about V-Play Live Code Reloading in this post.

 

What’s Next for the V-Play Cloud IDE for QML

Currently the run button might also be displayed for code examples in the documentation that will not run successfully.

The majority of examples and code snippets from the V-Play Apps documentation is working fine already, and while you’re reading this the games documentation is finalized as well. This means you can already start working with the Web Editor and start saving development time!

We will update the V-Play Live Scripting app next week with an improved user interface and a project cache. You will be able to open your projects on your mobile phone also when not connected to your desktop, to show it to friends, customers or to yourself. :)

The next steps are then support for autocompletion, integrated help and Git support. This allows you to work on the same project on Desktop (with Qt Creator or any other IDE you prefer) and the web, with the V-Play Cloud IDE for QML code.

More QML Code Examples

QML Map Example

web-editor-example-map

Displays a map using the MapBox service.

import VPlayApps 1.0
import QtLocation 5.5

App {
  NavigationStack {
  
    Page {
      title: "Map Example"
    
      // show the map
      AppMap {
        anchors.fill: parent
        plugin: Plugin {
          name: "mapbox"
          // configure your own map_id and access_token here
          parameters: [  PluginParameter {
              name: "mapbox.mapping.map_id"
              value: "mapbox.streets"
            },
            PluginParameter {
              name: "mapbox.access_token"
              value: "pk.eyJ1IjoiZ3R2cGxheSIsImEiOiJjaWZ0Y2pkM2cwMXZqdWVsenJhcGZ3ZDl5In0.6xMVtyc0CkYNYup76iMVNQ"
            },
            PluginParameter {
              name: "mapbox.mapping.highdpi_tiles"
              value: true
            }]
        }
      
      }
    }
  }
}

QML List  Example

web-editor-example-listview

Shows a simple list with a button to add new list items.

import VPlayApps 1.0

App {
  NavigationStack {
  
    Page {
      id: page
      title: "Add List Items"
    
      // the data model for the list
      property var dataModel: [
        { text: "Item 1" },
        { text: "Item 2" },
        { text: "Item 3" }
      ]
    
     // button to add an item
      AppButton {
        id: button
        anchors.horizontalCenter: parent.horizontalCenter
        text: "Add Row"
        onClicked: {
          // create and add new item
          var itemNr = page.dataModel.length + 1
          var newItem = { text: "Item "+itemNr }
          page.dataModel.push(newItem)
        
          // signal change in data model to trigger UI update (list view)
          page.dataModelChanged()
        }
      }
    
     // list view
      AppListView {
        id: listView
        anchors.top: button.bottom
        anchors.bottom: parent.bottom
        width: parent.width
      
        model: page.dataModel
        delegate: SimpleRow {}
      }
    }
  
  }
}

QML AdMob Ad Banner Example

web-editor-admob-banner-example

Shows the easy integration of a native AbMob ad banner.

import QtQuick 2.0
import VPlayApps 1.0
import VPlayPlugins 1.0

App {
  NavigationStack {
    Page {
      title: "AdMob"

      AdMobBanner {
        adUnitId: "ca-app-pub-3940256099942544/6300978111"
      }
    }
  }
}

QML Physics Example

web-editor-example-ball

Simple game example where gravity pulls a ball downwards.

import VPlay 2.0
import QtQuick 2.8

GameWindow {
  Scene {
    EntityManager {
      id: entityManager
    }

    // gravity will pull the ball down
    PhysicsWorld {
      gravity.y: 9.81
    }

    // just a simple ball shaped entity
    EntityBase {
      id: entity
      width: 20
      height: 20
      x: 160
      y: 240

      Rectangle {
        anchors.fill: parent
        color: "red"
        radius: 10
      }

      // the collider enables physics behavior
      BoxCollider {
        id: collider
        anchors.fill: parent
      }
    }

    // this timer resets the ball after 3 seconds
    Timer {
      running: true
      interval: 3000
      repeat: true
      onTriggered: {
        entity.x = 160
        entity.y = 240
        collider.linearVelocity = Qt.point(0,0)
      }
    }
  }
}

 

You can find more code examples everywhere in our documentation.

The code snippets page is a compilation of several useful code examples for apps.
Go to Code Snippets Page

 

 

More Posts Like This


v-play-live-reloading-windows-mac-linux-ios-android-qt

Release 2.14.0: Live Code Reloading for Desktop, iOS & Android


feature

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

The post Web Editor: Test Online Code Examples on Android and iOS with Live Code Reloading appeared first on V-Play Engine.

Qt 5.10.1 Released

I am pleased to inform that Qt 5.10.1 is released today. As a patch release, Qt 5.10.1 does not add any new functionality but provides many bug fixes and other improvements.

Compared to Qt 5.10.0, the new Qt 5.10.1 contains over 300 bug fixes and in total close to 1400 changes since Qt 5.10.0. For details of the most important changes, please check the Change files of Qt 5.10.1.

Qt 5.10.1 can be updated by using the online installer’s maintenance tool. For new installations, please download the latest online installer from the Qt Account portal or from the qt.io download page. Offline packages are available for commercial users via the Qt Account portal and at via the qt.io download page for open-source users.

The post Qt 5.10.1 Released appeared first on Qt Blog.

Qt Creator 4.5.1 released

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

This is a pure bugfix release, please find the details in our changelog.

Our prebuilt binaries are based on Qt 5.10.1, which was also released today. Besides other things this fixes an annoying issue with override / wait cursors on Windows.

Get Qt Creator 4.5.1

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

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

Memory usage improvements in Qt3D

Together with engineers from KDAB and the Qt community, we are continuing to improve performance and stability of Qt3D. Back in November, I wrote about how we have reduced CPU usage in Qt3D. In this post I would like to share some improvements we have made to reduce memory consumption.

Qt 3D has a flexible architecture that separates the frontend, which runs on the GUI thread, from the backend, which consists of aspects responsible for rendering, input handling, and animation. The aspects are run on a separate thread and can start jobs that are run on a thread pool. This allows Qt 3D to make use of needed CPU resources in parallel, but it also means we need to keep data duplication to a minimum. By reducing the amount of duplicated data and improving the allocation strategy for backend objects, the memory usage has been significantly reduced.

Even small projects benefit from these improvements, such as the Simple C++ example, which uses no textures or other assets:

Simple C++ Example

On my Linux desktop, this example is down from 92 MB in Qt 5.6.3 to 47 MB on Qt 5.9.4:

Qt3D simple-cpp example RAM usage

The same can be seen in more complex applications, such as this internal demo application for an automobile instrument cluster. It is using Qt Quick and Qt 3D to render the dashboard of an electric car. The demo has a number of different views for navigation, media, and a consumption overview. It also renders a live 3D model of the car with multiple textures:

Qt3D and QtQuick instrument cluster

The memory usage in this example has dropped from about 220 MB of RAM in Qt 5.6.3 to 135 MB in Qt 5.9.4:

Qt 3D instrument cluster demo RAM usage

We are working hard to improve performance and stability further in upcoming releases. In Qt 5.10.1 we have improved on-demand rendering performance, while in Qt 5.11 we streamline the order in which rendering jobs are executed. This ensures stability and allows for more performance improvements in the future. In later releases, we will increase data caching between frames to reduce the amount of work even further.

The post Memory usage improvements in Qt3D appeared first on Qt Blog.

GammaRay 2.9.0 Release

We have released version 2.9.0 of our Qt application introspection tool GammaRay. GammaRay allows you to observe behavior and data structures of Qt code inside your program live at runtime. GammaRay 2.9 introduces a number of new features interesting to Qt Quick, QWidgets, Qt 3D and non-graphical Qt users alike.

Qt Quick

One focus area of this release is the paint analyzer. It got significantly improved argument inspection, stack traces for all operations, and, in addition to QWidgets, QGraphicsView and QQuickPaintedItem, it's now also available for the Qt Quick software renderer (with Qt 5.9.3 or newer) and Qt 3D painted textures. The paint analyzer now also measures the time each operation takes. With all that combined you have a powerful tool when being faced with rendering performance issues in applications using the Qt Quick software renderer.

GammaRay paint analyzer / profiler with a Qt Quick software renderer application.

 

For the Qt Quick OpenGL renderer we have some interesting new feature too of course, such as the texture inspection tab. This enables you to see the textures used on the GPU backing Image elements or Text elements using distance field rendering. This is useful to spot sub-optimal texture atlas usage, or textures containing unnecessary content, both of which can hurt GPU memory consumption. The texture inspection view supports analyzing this with diagnostic overlays, highlighting transparent borders or repeated areas that can for example be optimized by the use of BorderImage elements.

GammaRay texture inspector highlighting a largely transparent element in a texture atlas

 

Core Features

There's also new features for the non-UI aspects of Qt. The new QML binding inspector (requires Qt 5.10 or newer) allows you to analyze the dependencies of a QML property binding. It provides source code navigation to the corresponding binding dependency and thus is quite useful for debugging non-trivial binding loops.

GammaRay QML binding inspector showing a binding loop.

 

The new QObject creation stack trace view expands on the QObject creation source navigation we introduced in the previous release and also shows you the full stack trace leading up to the creation of a specific object (not available on all platforms). Very useful when you spot objects in GammaRay that shouldn't be there (anymore).

GammaRay object creation stack trace view.

 

Widgets

For QWidget users, the GammaRay widget inspector is now able to visualize the tab focus chain. This makes testing the tab order a lot more convenient than tabbing manually through a big dialog.

GammaRay tab focus chain visualization highlighting unexpected transitions.

 

Qt 3D

Qt 3D isn't forgotten either. The geometry inspector got a couple of extensions, such as vertex picking support and a number of new diagnostic shading modes that allow you to easily spot issues in e.g.  normal, tangent or texture coordinate attributes.

GammaRay Qt 3D geometry inspector visualizing the normal attribute of a vertex buffer.

 

And that's just scratching the surface, there's many more features and improvements in this release. You can find a full list of changes here.

If you like GammaRay, there's an easy way to support its development. Just enable telemetry data submission via 'Help > Contribute' in the GammaRay client. This allows us to see which platforms, Qt versions and tools are most relevant for you, so we can focus on those. Thank you!

GammaRay is available as part of Qt Automotive Suite including Qt Creator integration and professional support, or GPL-licensed on Github.

[training_callout] continue reading

The post GammaRay 2.9.0 Release appeared first on KDAB.

How to Access REST Services with Qt and V-Play: Weather Service Example App (Open Source)

REST and RESTful web services are the most common way to access data through the Internet. Qt with V-Play provides an easy way to connect via REST. This article guides you through the most important steps to create an App and connect to a REST service. Additionally, it provides reusable code snippets.

Spoiler: Basic REST Example with V-Play

Before we jump into the details of creating the sample App, this is how a basic request to a REST service looks, using the XMLHttpRequest:

// Create the XMLHttpRequest object
var xhr = new XMLHttpRequest

// Listen to the readyStateChanged signal
xhr.onreadystatechange = function() {
  // If the state changed to DONE, we can parse the response
  if (xhr.readyState === XMLHttpRequest.DONE) {
    // The responseText looks like this {"ip":"xxx.xxx.xxx.xxx"} 
    // Parse the responseText string to JSON format
    var responseJSON = JSON.parse(xhr.responseText)
    // Read the ip property of the response
    var ip = responseJSON.ip
    // Log your ip to the console output
    console.debug("My IP is: " + ip)
  }
}

// Define the target of your request
xhr.open("GET", "https://api.ipify.org?format=json")
// Execute the request
xhr.send()

Real-Life Sample Project

For the most useful results, we build a real-life Qt client. It accesses one of the web’s most popular weather services. It’s easy to adapt to any other REST service: the process is always the same. You only need to change the endpoint URL and parse the corresponding content.

Qt-Qml-V-Play-REST-Weather-App-300

The full sample is available open-source on GitHub:

 

Architecture

The app consists of two files:

  • Main.qml: contains the UI and REST logic
  • DataModel.qml: stores & caches the parsed data from the REST service

App Architecture for REST Services with Qt, QML and V-Play

Basic UI for a Responsive REST Client App

First, we create the user interface: the QML items in “Main.qml”. We use V-Play APIs. They adapt to the style of the target platform (Desktop, Android, iOS). These three items are usually present in every Qt / QML app:

  1. The App component is always the top-level element in the QML file. It adds a lot of vital layout data to standard Qt classes. Two mechanisms are especially important. Device-independent pixels (dp) for sizes and scale-independent pixels (sp) for fonts.
  2. Initially, our REST client app only has a single page. It’s still a good idea to add the NavigationStack item as a child. Later, it could handle navigating to a detail page. In our current app, the NavigationStack ensures that the top navigation bar is visible.
  3. The third item is the Page. It’s the container for the automatic title bar and the visible QML items of our app. The platform-specific theming is applied automatically.

Visualization UI

After the generic UI elements, we define the custom interface. The user enters the city name in a SearchBar. The AppText elements below show the parsed data / error message.

QML Page Layout

We need vertically stacked UI elements. The generic QML ColumnLayout is the best layout manager for this scenario. Its documentation is short. Essentially, it’s a convenience version of the GridLayout with a single column.

QML contains another class which looks similar at first sight: the Column. What’s the difference of ColumnLayout vs Column?

  • Column is a Positioner. It arranges QML items in a regular fashion (i.e., below each other). The child items are responsible for their size. The Column takes care of the position.
  • ColumnLayout is a Layout. In addition to the position, it also manages the child item size. This makes it more suitable for responsive user interfaces. It ensures the individual item’s place on the screen is a good compromise of the available space and the minimum item size.

We’re dealing with a mobile UI. Thus, the ColumnLayout is the better choice.

ColumnLayout {
    anchors.fill: parent
    anchors.margins: app.dp(16)
    // ... QML child items ...
}

To achieve the expected look & feel of the UI on a phone, we set two properties:

  • anchors.fill: parent – this stretches the layout to the available width and height.
    What happens if we don’t specify the layout size?
    The layout area would adapt to the minimum requested size of its managed QML items. The text items always grab the space they need for showing their contents. But the SearchBar is flexible: it takes what it gets and doesn’t have a minimum width. Therefore, the SearchBar would be too small or even invisible if we didn’t have enough text in the rest of the UI.
  • anchors.margins: app.dp(16) – text shouldn’t stick to the screen edge. The Google Material Design recommends screen edge left and right margins of 16dp. Note that in iOS, you should also consider the safe area in addition to the margins. This ensures your content is not within the cutout-areas of the iPhone X in landscape mode.
    In our app, we use a margin of 16 density-independent pixels. This ensures a similar spacing on all mobile phones, independent of the screen’s pixel density.

Data Input: SearchBar

Entering data for searching or filtering is a common task in every mobile app. Fortunately, V-Play includes an advanced QML item. It handles interaction and platform-specific theming. You get a full-blown search text input control by specifying a handful of settings. This screenshot shows an empty SearchBar with the iOS theme:

SearchBar for a REST client with Qt, QML and V-Play

SearchBar {
   id: weatherSearchBar
   focus: true
   Layout.fillWidth: true
   placeHolderText: qsTr("Enter city name")
   onAccepted: loadJsonData()
}

By setting the width to correspond to the parent’s width (-> the layout), we ensure the search bar always fills the available screen width. The placeHolderText is great for better usability.

Finally, with onAccepted, we call a custom JavaScript function that we will code shortly. This signal is emitted whenever the user presses the Return or Enter key.

Data Display: AppText

The AppText QML type is another component of V-Play. It is a styled QML Text item. It picks up the platform’s colors and styling by default.

Our layout consists of several AppText items. Each has a dynamic text property, which is bound to weather data from the DataModel. The layout ensures the items are below each other.

AppText {
   text: qsTr("Weather for %1").arg(DataModel.weatherData.weatherForCity)
   Layout.fillWidth: true
   wrapMode: Text.WordWrap
   color: Theme.tintColor
   font.family: Theme.boldFont.name
   font.bold: true
   font.weight: Font.Bold
   visible: DataModel.weatherAvailable
}

Let’s examine the most complex AppText item in our layout: the header of the weather information. It shows the city name and country.

  • Text: the city name is bound to our data model.
    To prepare for future app translation, we wrap the text string with qsTr(). Read more: How to Make a Multi Language App or Game with V-Play
  • Layout: some text might not fit in a single line. Therefore, we activate word wrapping. The QML item needs to have a width to know where to insert the line break. We set the width to fill the available space provided by the layout.
  • Styling: we apply a bold and colored style to the text. The global Theme item of V-Play provides app-wide and platform-adapted color and font resources.
  • Visibility: the item should only be visible if weather data is available in the model. The binding automatically adapts the visibility.

Remaining Screen Height

By default, the layout distributes the available screen height between all items. Our current layout is quite compact. We don’t want a huge unused area between each text line.

To solve this, we add an Item with an activated fillHeight property. It’s not visible on the screen but is as tall as possible. This pushes the other items together.

Item {
    Layout.fillHeight: true
}

Weather Services

The most popular weather services are OpenWeatherMap, Yahoo Weather and Weather Underground. In this tutorial, we use OpenWeatherMap. It’s quick to sign up, it provides free weather data access and is frequently used (also by Google).

API Key

Sign up for free at https://openweathermap.org/appid

Immediately afterwards, you get an email with usage samples. OpenWeatherMap already generated an API key called “Default” in your account.

Sign up for the ApiKey of OpenWeatherMap to use the REST Service

It takes around 10 minutes until the key is active. Click on the sample link in your welcome email to check if the service is already up and running for your account.

REST Request & JSON Parsing with Qt / QML

How do we fill the UI with actual weather data? Most Internet services provide a REST API. In Qt, QML and JavaScript are tightly integrated. Instead of having to resort to C++ code, we can use standard JavaScript code to access a RESTful API.

In technical terms, the XMLHttpRequest object is embedded in the QML Global Object. Its functionality corresponds to the W3C Standard. The only exception is that it doesn’t enforce the same-origin policy. This makes our life easier, as we do not have to deal with CORS (Cross-Origin Resource Sharing). In QML JavaScript, all REST requests typically go to an external web server.

You need 4 steps for a REST request:

  1. Instantiate XMLHttpRequest
  2. Register a state change listener
  3. Set the target URL & request properties
  4. Send the REST request

Let’s analyze these steps:

1. Instantiate XMLHttpRequest

In the first line, we create an instance of the XMLHttpRequest object. It’s OK to be a local object. Every REST request creates a new instance.

var xhr = new XMLHttpRequest

2. Register a State Change Listener

By default, XMLHttpRequest is asynchronous. Therefore, we define an event handler. The most flexible approach is attaching a handler function to the onreadystatechange event.

During the lifetime of the REST request, it runs through several states:

  1. UNSENT
  2. OPENED
  3. HEADERS_RECEIVED
  4. LOADING
  5. DONE <- request is finished. Is always called (also in case of an error!)

To provide progress indicators while loading, you could register for intermediate events. For quick requests like ours to a weather service, it’s usually enough to only handle the DONE event.

xhr.onreadystatechange = function() {
   if (xhr.readyState === XMLHttpRequest.DONE) {
       // ... handle response data ...
   }
}

3. Set the Target URL & Request Properties

Next, we configure the REST request. The open() function needs at least two parameters:

  • Method: the HTTP method for the REST request. The REST protocol allows full interaction with a server.
    To retrieve data, you use GET or POST methods (depending on the service definition).
    An interactive RESTful web service can also implement the PUT, PATCH and DELETE methods for modifying data.
  • Url: target to invoke. In case of a GET request, the parameters are part of the URL.

The open() function checks the data you supply and advances the request state to OPENED.

The OpenWeatherMap service works using GET requests. The URL needs to contain:

  1. Query: the city name, e.g., ?q=Vienna
    We retrieve the query string from the text of the weatherSearchBar QML item.
  2. Units: metric or imperial, e.g., &units=metric
  3. API key / App ID: sign up to get a free app id. E.g., &appid=xyz
    It’s a good idea to store your API key / App ID as a property in your app.

The full code to construct the query URL and to open the REST request:

var params = "q=" + weatherSearchBar.text + "&units=metric&appid=" + app.weatherServiceAppId
xhr.open("GET", "http://api.openweathermap.org/data/2.5/weather?" + params)

4. Send the REST Request

A simple statement. If your RESTful service uses POST, you supply the body as parameter. For our GET method, call:

xhr.send()

Parse the REST Response

Once our REST request proceeds to the DONE state, we check the results. As we call an external service through the Internet, many things can go wrong. It’s important to handle all possible failures.

Most REST / JSON tutorials show a simplified handler. It’d fail without an Internet connection. Here, we handle all possible issues.

JSON Response

If everything went well, we received a response. The responseText property contains the JSON data, which we parse through JSON.parse(). This is the shortened JSON response. The full OpenWeatherMap response contains more data.

{
  "weather": [
    {
      "main": "Snow",
      "description": "light snow",
      "icon": "13n"
    }
  ],
  "main": {
    "temp": -0.32,
  },
  "name": "Vienna",
  "cod": 200
}

Identify Failed REST Requests

A request can fail because of several reasons:

  • Connection issues: e.g., no Internet connection or the server is down
  • Request issues: the server / service does not understand your request, e.g., due to a typo in the URL
  • Access issues: the RESTful service can’t fulfil your request. Examples: unauthorized client, invalid API key
  • Service issues: unable to send a positive response. E.g., because the requested city doesn’t exist, or because no weather is currently available for the city

Usually, REST services only send the positive HTTP status code 200 if everything worked well. In all other cases, they send a different HTTP status code (e.g., 404 if the city wasn’t found). Additionally, it may send a response text even in case of a failure. This provides extra information on what went wrong.

But, some REST services always return the successful HTTP code 200. They only report an error in the response text. Check the service documentation and test the REST APIs.

OpenWeatherMap is a well-designed RESTful service. It always sends a response JSON. The JSON data includes a response code (called “cod”). So, it’s best to parse the responseText (if available). If parsing the JSON was successful (!= null) and the JSON contains a “cod” of 200, we know that everything went well. Otherwise, we need to analyze the error.

var parsedWeather = xhr.responseText ? JSON.parse(xhr.responseText) : null
if (parsedWeather && parsedWeather.cod === 200) {
   // Success: received city weather data
} else {
   // Issue with the REST request
}

Successful REST Request

If the REST service returned data, we reset any previous error message in our UI. Then, we update our DataModel.

// Success: received city weather data
app.errorMsg = ""
DataModel.updateFromJson(parsedWeather)

REST Response Error Handling

In technical terms, we differentiate 3 types of REST request failures:

  1. The status code of the XMLHttpRequest is still 0, even though its status already changed to DONE. This indicates that the request didn’t go through.
    Potential reasons: no Internet connection, server is down, …
  2. We received response text, but it contains an error description. For our weather app, we show the message to the user.
    Potential reasons: city not found, API key is wrong, …
  3. No response text, but a HTTP response status code. Create a custom error message for the user.
    Potential reasons: REST service crashed (e.g., 500 Internal Server Error), …

This code snippet handles all 3 cases. It formulates a brief error message for the app user.

// Issue with the REST request
if (xhr.status === 0) {
   // The request didn't go through, e.g., no Internet connection or the server is down
   app.errorMsg = "Unable to send weather request"
} else if (parsedWeather && parsedWeather.message) {
   // Received a response, but the server reported the request was not successful
   app.errorMsg = parsedWeather.message
} else {
   // All other cases - print the HTTP response status code / message
   app.errorMsg = "Request error: " + xhr.status + " / " + xhr.statusText
}

JSON Data Model for REST Requests

An architecture that separates the model from the view makes your app easy to extend. So, we create an extra class to manage the data model.

Right-click the qml folder in Qt Creator’s “Project”-window and select “Add new…”. Choose the Item template in the V-Play Apps category. Call the file “DataModel.qml”.

Singleton Pattern in QML

We want our model to be accessible in the whole app. Thus, we use the Singleton pattern. This requires three steps:

1. Prepare the QML file

In the very first line of DataModel.qml – before the import statements – add:

pragma Singleton

2. Register the singleton

Create a new file called “qmldir” in Other files > qml in the Projects window.

Register a Singleton through the Qmldir in Qt

Add the following line to the qmldir file:

singleton DataModel 1.0 DataModel.qml

In the next step, we’ll import a directory to access our singleton file. When importing a directory, Qt always looks first for a qmldir file. It’s using that to customize the way it sees and imports qml files. In our case, the QML engine now knows to treat the DataModel.qml file as a singleton.

3. Import the Singletons

In Main.qml, add the following import after all the other import statements:

import "."

This causes Qt to scan the directory. From now on, our DataModel.qml file is accessible via the “DataModel” identifier in Main.qml.

QML Data Model Structure

Our data model requires three properties. Two contain information about the state of the data (weatherAvailable and weatherFromCache).

The third property is weatherData. It’s defined with the type var and initialized as an array with []. This allows assigning key-value pairs for the actual data. It lets us cache and restore the data with a single statement. Dynamic binding to the UI is still possible.

The basic structure of our data model:

pragma Singleton
import VPlay 2.0
import QtQuick 2.7

Item {
   id: dataModel

   property bool weatherAvailable: false
   property bool weatherFromCache: false

   property var weatherData: []
}

Save Weather Data to the Model

We want to keep the model generic. You could add a different data provider later, or the JSON layout changes.

Our app extracts the data it needs from the weather JSON. The app then stores the relevant data in its own model. If we’d later migrate to a different data provider, it wouldn’t influence the model or the UI.

The most efficient way to achieve this: create a setModelData() function. It takes the parsed parameters and saves it to our weatherData property.

function setModelData(weatherAvailable, weatherForCity, weatherDate, weatherTemp, weatherCondition, weatherIconUrl, weatherFromCache) {
    dataModel.weatherData = {
           'weatherForCity': weatherForCity,
           'weatherDate': weatherDate,
           'weatherTemp': weatherTemp,
           'weatherCondition': weatherCondition,
           'weatherIconUrl': weatherIconUrl
           }

    dataModel.weatherAvailable = weatherAvailable
    dataModel.weatherFromCache = weatherFromCache
}

Parse JSON Data from the Weather Service

In a previous step, we already converted the JSON text to objects with JSON.parse(xhr.responseText).

The QML runtime implements the ECMAScript language specification. Thus, working with JSON data in QML is like standard JavaScript. Every JSON object is accessible as a property. You retrieve JSON array values using the [] accessor.

The updateFromJson() method extracts the useful information from JSON and forwards it to our model.

function updateFromJson(parsedWeatherJson) {
   // Use the new parsed JSON file to update the model and the cache
   setModelData(true,
                parsedWeatherJson.name + ", " + parsedWeatherJson.sys.country,
                new Date(),
                parsedWeatherJson.main.temp,
                parsedWeatherJson.weather[0].main,
                "http://openweathermap.org/img/w/" + parsedWeatherJson.weather[0].icon + ".png",
                false)
}

Note: JavaScript and QML are very similar. The differences are hard to spot.

We choose the Qt variant, as it makes serialization easier. Qt provides platform-independent storage and transmission of all Qt data types.

Now, the app is functional! Go ahead and test it on any platform or device.

Data Persistence

REST requests over the Internet take time. To improve the user experience, we add data persistence to our app. With this enhancement, our app immediately shows cached data when it’s started. The update request to the webservice then runs in the background.

We stored our weather data in DataModel.qml. Now, we extend our model to encapsulate its own caching.

Storage QML Type

File handling is different on every platform. V-Play includes a powerful cross-platform type called Storage. It handles the most common use-case: key-value data storage. You don’t need to write complex SQL statements like in the base Qt Quick Local Storage QML type.

At the same time, all built-in QML types are serializable to Strings. With a single line of code, we export the whole model to persistent storage.

Initialize the Storage by adding the element as a child of our dataModel item:

Storage {
   id: weatherLocalStorage

   Component.onCompleted: {
       // After the storage has been initialized, check if any weather data is cached.
       // If yes, load it into our model.
       loadModelFromStorage()
   }
}

Load QML Data from Persistent Storage

The ready-made implementation from V-Play calls onCompleted() once the storage is accessible. We use this to check if cached data is available. We access stored data using getValue(). If no data is available, it returns undefined. A simple if(savedWeatherData) statement lets us execute code accordingly.

function loadModelFromStorage() {
   var savedWeatherData = weatherLocalStorage.getValue("weatherData")
   if (savedWeatherData) {
       dataModel.weatherData = savedWeatherData
       dataModel.weatherAvailable = true
       dataModel.weatherFromCache = true
   }
}

The powerful APIs de-serialize the storage into the live model data. To inform the user that he’s now seeing cached data, we set the other model properties accordingly.

Save QML Data to Persistent Storage

To serialize our weather data to the storage, we use setValue(). The second argument is our whole weather data storage object. V-Play automatically serializes it to the storage.

function saveModelToStorage() {
   weatherLocalStorage.setValue("weatherData", dataModel.weatherData)
}

What’s the best place to update the storage? Especially in mobile apps, it’s recommended to immediately update persistent storage. A mobile operating system may shut down apps at any time, e.g., for an incoming call and low system resources. Thus, call saveModelToStorage() at the end of our setModelData() method.

Deploy the App to Android, iOS and Desktop

V-Play provides platform-independent styling and a responsive layout. The V-Play Live Service features live code reloading every time you save changes to QML files. The PC client simulates the app appearance on iOS, Android or Desktop platforms.

With the V-Play Live Scripting App for Android or iOS, you can extend testing to a real mobile device. Your development PC and the phone communicate over the local area network.

This screenshot shows a sample configuration of the V-Play Live Server. Two clients are connected. The app is running on a Google Pixel 2 phone (with the V-Play Live App) and on a desktop client.

V-Play Live Server with 2 connected clients  REST Client with V-Play running on a Google Pixel 2

Download the final, open source QML REST client sample code from GitHub:

It extends the code from this article with several comments. It’s a great starting point for your own REST projects!

 

 

More Posts Like This


v-play-live-reloading-windows-mac-linux-ios-android-qt

Release 2.14.0: Live Code Reloading for Desktop, iOS & Android


feature

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

The post How to Access REST Services with Qt and V-Play: Weather Service Example App (Open Source) appeared first on V-Play Engine.

Qt Creator 4.6 Beta released

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

C++ Support

The possibly most noteworthy and least directly visible change is that we upgraded the backend for the Clang code model from Clang 3.9 to Clang 5.0. This enables support for many C++17 features that were not available in Clang 3.9. The Clang code model is not used by default. Open Help > About Plugins (Qt Creator > About Plugins on macOS) and turn on the ClangCodeModel plugin to enable it.

Another feature that is not visible until you enable it, is the new option to integrate Clang-Tidy and Clazy warnings into the diagnostic messages that you see in the C++ editor. Go to Options > C++ > Code Model > Clang Code Model Warnings, create a copy of one of the presets, and choose the checks that you want to be performed.

The informational tooltips on symbols are now generated from information from Clang instead of the built-in model (if you enabled the Clang code model). It now resolves auto to the actual type and shows template parameters for template types. It shows the first or the \brief paragraph of a documentation comment, too.

We also added separate highlighting of function definitions and fixed some issues with saving header files on Windows while Clang has a grip on them.

Navigation

We added 3 more filters to Locator. Type “b<space>” to jump to a bookmark, filtering on file name and notes. The other two are not directly related to navigation but nevertheless useful.
The filter “t<space>” triggers an item from the main menu. You can either use the display name of the item to locate it, or parts of the menu path leading to it. For example “t sess expe” could be used to trigger the menu item File > Sessions > Experimental Stuff.
Use “=<space>” to evaluate simple ECMAScript (JavaScript) expressions. You have all functionality from the ECMA-262 specification at your disposal, and for convenience, we also added the functions from the Math object as global functions (so you can write “max(1, 2)” instead of “Math.max(1, 2)”).

We continued the work on the File System navigation pane that we started with 4.5. It now has breadcrumbs for the file path at the top, and we added actions for adding, removing, and renaming files to its context menu.

Model Editor

Thanks to Jochen, the original contributor to the model editor, it received a big update in this release. It now supports text alignment and multi-line object names. You can export only selected elements or the whole diagram to images. A wider range of panes now supports drag & drop of items. Enable the model editor by enabling the plugin in Help > About Plugins (Qt Creator > About Plugins on macOS).

There have been many more improvements all over Qt Creator. Please have a look at our changelog for a more detailed overview.

Get Qt Creator 4.6 Beta

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

Sharing Files on Android or iOS from or with your Qt App – Part 3

by Ekkehard Gentz [Independent Software Architect, Consultant] (Qt Blog)

Welcome to Part 3 of my Blog series about Sharing Files to and from mobile Qt Apps.

Part 1 was about sharing Files or Content from your Qt App with native Android or iOS Apps, Part 2 explained HowTo share Files with your Qt App from other native Android Apps – this part now does the same from other native iOS Apps.

01_blog_overview

Some preliminary notes

  • Try it out: all sources are available at ⦁ GitHub
  • Android Permissions not checked in Example App: enable WRITE_EXTERNAL_STORAGE manually
  • Current Android release is for Target SDK 23 ! (Android 7 requires ⦁ FileProvider – wait for Blog Part 4)
  • All Use-Cases are implemented to be used x-platform – currently Android and iOS

If you‘re looking for an Android-only solution please also take a look at AndroidNative project.

Prepare iOS Info.plist

Similar to Android intent-filter in AndroidManifest.xml we must add some informations to Info.plist. If you haven‘t already done copy the Info.plist from your build directory into your project:

02_info_plist_in_project

Then add this into your .pro:

ios {
    ...
    QMAKE_INFO_PLIST = ios/Info.plist
    ...
}

Open the Info.plist and insert these lines:

<key>CFBundleDocumentTypes
  <array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>Generic File</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSHandlerRank</key>
        <string>Alternate</string>
         <key>LSItemContentTypes</key>
           <array>
              <string>public.data</string>
           </array>
    </dict>
  </array>

See all the details from Apple Documentation „Registering File Types“.
Here‘s a short overview how the Types are organized:

03_uniform_type_identifiers

public.data is similar to MimeType */* we are using to filter Android Intents in our Example App.

After adding the lines to Info.plist our App will appear as a target App if Files or Attachments should be shared from other iOS Apps.

Fortunately iOS doesn‘t provide our own App as target if we want to share Files from our Example App with other iOS Apps.
Remember: On Android we had to create a custom Chooser to filter out our own App as target.

Get the incoming URL

The Files from other iOS Apps will be passed to the Qt App via application:openURL:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

see also Apple documentation.

From Part 2 (Android implementation) you know that we have to wait until the Qt App is ready to handle the incoming URL and be able to emit a SIGNAL to QML UI.

We don‘t need this for iOS, because there‘s a Qt method we can use out of the box and grab the passed file url by registering QDesktopServices::setUrlHandler:

QDesktopServices::setUrlHandler("file", this, "handleFileUrlReceived");

This is easy to implement. We already have the IosShareUtils.mm class where we handle sharing Files to other Apps. Adding some lines of code:

IosShareUtils::IosShareUtils(QObject *parent) : PlatformShareUtils(parent)
{
    QDesktopServices::setUrlHandler("file", this, "handleFileUrlReceived");
}

void IosShareUtils::handleFileUrlReceived(const QUrl &url)
{
    QString myUrl = url.toString();
    // … remove "file://" from Url
    // … then check if File exists
    QFileInfo fileInfo = QFileInfo(myUrl);
    if(fileInfo.exists()) {
        emit fileUrlReceived(myUrl);
    } else {
        emit shareError(0, tr("File does not exist: %1").arg(myUrl));
    }
}

That‘s it 🙂

Thank You @taskfabric

Seems this is the first time I can tell you that there‘s easy stuff to manage Filesharing from Qt,
but I never would have found it out by myself. Didn‘t expected to take a look at QDesktopServices for sharing File URLs on Qt Mobile Apps.

Thanks to Thomas K. Fischer from Taskfabric.com who offered help at Qt Blog Comment
This is the real value of a great Qt Developer Community: Thomas appreciated my work on this sending me some lines of Code and pointing me to QDesktopServices. As a result it was easy for me to implement and publish the updated Sharing Example at Github.

Overview

Here‘s a short Overview about the iOS implementation:

04_handle_url_from_ios_apps

Test it!

Now it‘s a good point to test it.

Open „ekkes Share Example“ and navigate to one of the Tabs.

Open per ex. Apple Keynote App to share a File.

Here‘s the workflow from Apple Keynote App.
Tap on the SHARE Button:

05_keynote_share_01

Select „SEND COPY“:

06_keynote_share_02

„ekkes Share Example“ appears as Target:

07_keynote_share_03

Select ‚ekkes SHARE Example‘ and iOS will open the App. The App was already opened, so the current selected Page will be displayed and include a message about the received File.

08_keynote_share_04

So it works 🙂

No Qt Support for iOS Share Extensions

Attention: Sharing with a File URL works for all Apps providing Files or Attachments, but to handle Text or embedded Images shared from other Apps needs to be implemented with a “share extension”. See the details here.

Share Extensions are easy created using Xcode, but …
This is quite tricky to use with Qt, as the extension needs to be registered in Xcode and qmake overwrites the Xcode file on each run.

So Share (and other) Extensions cannot be included automatically while building from QtCreator and breaks workflows. See discussions https://bugreports.qt.io/browse/QTBUG-40101.

Hopefully Qbs will support this in the near future, because iOS App Extensions are an essential feature of iOS Apps in the meantime.

Some issues from Sharing Files to other Android Apps

Android: Sharing from Microsoft Word (and other MS Office Apps)

There are differences between Android 6 and Android 7 versions of MS Office Apps.

In both cases the Qt App received a SEND Action and a Content Url

MS Word:

content://com.microsoft.office.word.fileprovider/94161e0b-e48a-4142-9785-d0602d801e95/test.docx

Using QSharePathResolver.java class this File Url could be constructed:

/data/user/10/com.microsoft.office.word/files/tempOffice/Share/ff3251b4-c475-48e2-a7cc-f1df02d69874/test.docx

On Android 6 Devices the File Url could be opened and read without any problems from QFile – on Android 7 Devices I got a „File does not exist“ Error.

Other Apps using SEND Actions and Content Urls are working same on Android 6 or Android 7 Devices, so it‘s something special with MS Office Apps.

Testing some other ways to handle the File Url I found out that on Android 7 Devices for MS Word I can use InputStream for the given FileUrl. So I added an extra check for situations like this:

public class QShareActivity extends QtActivity
{
        // ...
    public static native boolean checkFileExits(String url);
}

bool AndroidShareUtils::checkFileExits(const QString &url)
{
    QString myUrl;
    if(url.startsWith("file://")) {
        myUrl= url.right(url.length()-7);
    } else {
        myUrl= url;
    }
    QFileInfo fileInfo = QFileInfo(myUrl);
        return fileInfo.exists();
}

JNIEXPORT bool JNICALL
  Java_org_ekkescorner_examples_sharex_QShareActivity_checkFileExits(JNIEnv *env,
                                        jobject obj,
                                        jstring url)
{
    const char *urlStr = env->GetStringUTFChars(url, NULL);
    Q_UNUSED (obj)
    bool exists = AndroidShareUtils::getInstance()->checkFileExits(urlStr);
    env->ReleaseStringUTFChars(url, urlStr);
    return exists;
}

Android: Sharing from Google Docs App fails if Qt App is open

In Android Manifest the Launch Mode is declared as

android:launchMode="singleInstance" android:taskAffinity=""

SingleInstance is the only launchMode where always the same instance of our one and only Activity will be opened. This enables workflows where User already logged into an App and navigated to a Page and if shared from another App exactly this Page will be displayed.

This works well and you can test it from „ekkes Share Example“ App: Open the App, select a specific Tab (Page), then open another App and share a File with the Example App. Our Example will be opened exactly on the selected Page.

If the App was open, onNewIntent() from our customized Activity should be called, but Google Docs always calls onCreate() – doesn‘t matter if the Target App is already running or not. Then a white screen comes up, the App hangs and must be closed. The Debug Log reports:

E Qt JAVA : Surface 2 not found!

I haven‘t found a way to workaround this yet – perhaps anyone else has an idea HowTo fix ?

Have Fun

Now it‘s time to download current Version from Github, build and run the Sharing Example App.

Stay tuned for the next part where FileProvider will be added to share Files on Android.

The post Sharing Files on Android or iOS from or with your Qt App – Part 3 appeared first on Qt Blog.

Qt Premium Support: Learning and Experiences

The Qt Company Support Team works hand-in-hand with Qt R&D developers, and we are 100% committed to ensuring your success. It’s now been a bit over half a year since we launched the new Premium Support service. We felt that now would be a good time to recapture its essence and the experiences of our teams and customers. We will be sharing lots of troubleshooting tips and best practices on March 6th, in our Qt Support – Tips and Tricks webinar – make sure to join and tell us about your project! In the meantime, here’s a brief recap of what we’ve been working on.

Qt Support Services

Standard Support is included with all new commercial Qt licenses (apart from start-up licenses). This guarantees that we respond to your request within 48 business hours and prioritize your reported Qt errors. However, many of our customers require more personal and quicker support service. This is where Premium Support comes in. It offers a dedicated support representative close to your time zone who will respond to you within 10 business hours on average. This means that if we get your request in the morning you can see our response before you leave work.

When we try to reproduce any issues you may have, we can also use your complete applications instead of minimal test versions to analyze issues and fix bugs. Premium Support reported Qt bugs also get high priority and will get handled quickly.

You can find the SLA terms on our webpage.

Experiences from Premium Support

We’ve resolved oodles of bug fix requests for our Premium Support customers. With Premium Support it doesn’t really matter whether the issue lies in your code or in the Qt libraries. We will investigate and find the solution no matter what. Typically bugs can be difficult to resolve in Standard Support since a minimal test application is required and some of the issues are really hard to reproduce with anything else than customer application. Being able to use customer application really speeds up resolving bugs!

We have also been providing a lot of guidance on best practices on particular use cases for our customers. This includes ideal usage of Qt APIs and what can be done within the customer application, algorithm guidance, architecture design and optimizing performance.

Another type of project we are often involved in is the migration from obsolete Qt version to a newer Qt5 version. Although almost everything works out-of-the-box when upgrading Qt, there are cases that require changes to the code. If you have a large codebase, it’s tedious to check whether some functionality has changed in a newer Qt version. Other times an upgrade comes with new features that make it easier to implement certain user application functionalities. This is where we can help you a lot since we know all the details of Qt and changes between versions.

Even though we can’t guarantee that all reported bugs will get fixed in a specific way, we have been able to find a usable workaround. That way you will never be stuck with your issues for long.

The Feedback from our Customers

Our customers have been genuinely happy with our service and gave us lots of great feedback on how we resolved their issues and clarified any doubts they might have had on certain topics.

We chose Qt Commercial because, firstly – we needed support. Time to market was critical for us, and to be able to ensure that we have timely responses to any important technical questions that came up was very important to maintain the pace of development. ’

– James Patterson, Technical Director, Co-Founder, Eykona Technologies

“We purchased an enterprise contract with The Qt Company because Qt gives us the expressiveness and the speed of a native UI framework with a very low maintenance cost and a nice support network behind us. We believe Qt will further our mission of providing the best user experience for our customers.’’

– Adam Christian, Senior Software Engineer, Tableau

“The support for free is amazing – the support for commercial is outstanding. If you want to feel that, you, the humble developer matters – use these guys. You are not only heard – if you lift your game with logging problems (give them a definite example of what is wrong, steps to reproduce, what you expect) – they 99% are fixed next release. New features, slight changes too. These guys are good. I’m a bit of a newcomer, only a year and a half using Qt but I’m a big fan.’’

– Reddit fan /u/6thComm

If you want to get or find out more about Premium Support, don’t hesitate to contact your account representative, or simply drop us a line.

The post Qt Premium Support: Learning and Experiences appeared first on Qt Blog.

Medical Device Design & Manufacturing Challenges: 2017 And Beyond

Near the end of 2017, Med Device Online published an article outlining important medical device design and manufacturing challenges at present and would extend into 2018 and beyond.

Working with Qt, and developing on the innovative, safe, and effective Qt software framework, we help companies meet and overcome these challenges medical device developers and manufacturers face.  The following is a list of the challenges outlined in the Med Device Online article and the Qt response:

  • Beating the Competition with Innovation
    You can create modern User Experiences with uncompromising performance & reliability. Build safe, effective, and reliable user interfaces and user experiences on almost any embedded device or mobile device platform.
  • Anticipating Rising Costs & Regulatory Changes
    The Qt Company has a very experienced and diverse partner ecosystem. Leveraging our close relationship with The Emergo Group allows our customers to better understand and anticipate the effects of pending regulations. Through this partnership our customers can best align their product development cycle with the regulatory certification cycle, making their overall go-to-market process (development + regulatory) faster and more efficient.
  • Streamlining R&D Amid Shorter Product Life Cycles
    During a recent customer survey, 84% of Qt’s customers state that their development teams are more productive using Qt. When asked how much productivity increased, their response was that productivity went up nearly 100%, or doubled, what it did when they weren’t using Qt. Qt allows you to do more work with less people in shorter amounts of time. If your software is intended to live on different types of platforms, you will not need a separate software development team for each platform with which it is to be compatible. The User Interfaces and User experiences created on Qt can reside on mostly any embedded or mobile platform with one code base. Simply code and compile to iOS, MacOS, Windows, Android, Embedded Linux, QNX, and many others.
  • A Need For Growing Support Networks
    The Qt Company has a very experienced consultancy group and that can help streamline R&D processes and uncover new, “outside the box” opportunities to compete on innovation. Our Qt consultants combined with our industry leading partnerships help our partners streamline time-to-market while enhancing safety and effectiveness.

We at The Qt Company are happy to help companies to design safe, efficient and user-friendly medical devices. Read more about our offering for the medical industry at www.qt.io/qt-in-medical.

The post Medical Device Design & Manufacturing Challenges: 2017 And Beyond appeared first on Qt Blog.

Boost your IoT Device with Qt

Here at guh GmbH, the creators of the IoT platform nymea, we have been using Qt since right from the start. You may think: it seems an odd choice to use Qt for a device with no UI requirements but just middleware components basically invisible to the user. Let me explain why this definitely isn’t the case. Essentially, there are three misconceptions in the previous statement.

nymea1

UI Framework: Yes, but so Much More

The first and biggest misconception is that Qt only focuses on UI projects. It is true that Qt started as a UI toolkit many, many years ago. But since then, Qt has evolved into a fully featured set of libraries and tools supporting the developer in every layer of the stack. Even if you don’t need graphical bells and whistles, Qt will increase your productivity by an order of magnitude. I’ll go a bit more in depth later on.

UI has Many Faces

Now, let me address the second misconception in the above statement: that no display equals no UI. Even when you’re building an embedded device without display, there’s hardly no user interface for it. In our example the user interface consists of a web interface running on the IoT box and a client app. The client application, running on mobile phones, PCs or just wall-mounted displays is mostly a thin UI layer, talking to the device. Here, Qt Quick can deliver a smooth, modern experience with a “write once, run everywhere” application. And the coolest part: since Qt 5.10, this very same client application can be re-used as the web interface on the device deploying the new Qt WebGL features.

No More Overhead: Deploy Only What You Need

Another comment I’ve often heard is that importing Qt into an embedded device would be a huge overhead. While in the early days, Qt was built of some few, rather big modules, this has changed a long time ago. At the very latest with Qt5, the modularization of Qt has facilitated fine-grained control of what parts of Qt are needed for a small footprint installation. However, in recent days this has been taken even further, and with Qt for devices it is now possible to strip down the required components to the real bare minimum, invalidating this point completely.

nymea3

How Qt has Increased Our Productivity Building nymea:

As mentioned above, I’d also like to address some of the features of Qt which have helped increase the productivity of nymea tremendously.
There are too many to list them all here, but the most important ones for our middleware stack are:

  • Plugin architecture: Qt’s plugin architecture is a perfect fit to load plugins, taking away all the complexity of finding and loading libraries. With nymea being built based on plugins, this constitutes a significant advantage. The core of the platform is a piece of software managing configurations and the “smartness” of things. All the actual hardware and online services, so called “things”, are enabled in the system via plugins.
  • Transport protocols: Just a few calls to the Qt APIs are all it takes. nymea’s middleware offers interfaces via sockets (TCP/IP or local sockets), WebSockets, REST and Bluetooth RFCOMM. All of those are simply at hand with Qt, using SSL encryption, providing certificates for secure communication.
  • JSONRPC based API: Qt offers support for JSON and allows easy conversion between internal data structures into JSON objects. This is a huge plus for us since nymea speaks a JSONRPC based protocol when interacting with clients.
  • Testing and debugging framework: Developers enjoy the advantages of a highly abstracted API. nymea’s codebase is studded with autotests using Qt Test. This turns writing test cases into an easy task and facilitates printing test reports and statistics in a variety of common formats (like UnitXML). Additionally, it enables integration with other existing frameworks for testing and debugging like coverty, Valgrind and all the other tools out there, as in the end, for those it’s just good old C++.
  • API documentation using QDoc: Qt offers an amazing documentation on doc.qt.io. QDoc enables doc generation directly out of the code through the CI setup and allows flexible custom styling while still preserving the clean look and feel of Qt docs. For nymea (https://doc.nymea.io/) as a platform which enables third-party developers to add their hardware/service such documentation is obviously essential.
  • A ton of small helpers all along the way: Qt offers an uncountable amount of features coming in handy while developing a headless application. From command-line argument parsing and log output filtering to online connectivity, various IPC mechanisms in the system (e.g. D-Bus) etc. Every feature is just ready to use with minimal effort.
  • All (or pretty much all) of this comes in a completely cross platform manner. While nymea is focused to run on Linux based devices, thanks to Qt it can be built for just about any platform. Of course, some platform integrated features like D-Bus APIs won’t work on all platforms, but those are very rare exceptions. Currently, nymea has a dpkg based repository for all supported Ubuntu and Debian distributions as well as snap packages for snap based systems. The client app is built for desktops and Android targets. Our team is also working on enabling iOS and the WebGL based version to have a fully Qt Quick based web interface for nymea, all out of a single codebase.

The gist of all this: Qt is an ideal framework whether your project includes a UI or not. Its high number of well-tested, high-quality APIs make every developer’s life that much easier, especially as those APIs are super easy to understand. Meanwhile, Qt still allows you to enjoy all the advantages of C++. So as you can see Qt is perfect for IoT.

guh-logo

About nymea: nymea makes your product smart. Fast, plannable, and hassle-free. Our M2M stack guarantees effortless API integrations. We believe in the strength of integrated edge solutions.

Meet us at Embedded World 27th Feb – 1st March 2018. Get your free ticket here: https://www.qt.io/ew-2018

The post Boost your IoT Device with Qt 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 {
 id: 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(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(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 simply available here because it is set as a context property in main.cpp
     Column {
       id: example1
       anchors.horizontalCenter: parent.horizontalCenter

       // 1.1: Calling myGlobalObject.doSomething() function
       AppButton {
         anchors.horizontalCenter: parent.horizontalCenter
         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 {
       id: example1
       anchors.horizontalCenter: parent.horizontalCenter

       // ...

       // 1.2: Increasing myGlobalObject.counter property
       // NOTE: the defined setter function of the property is used automatically and triggers the counterChanged signal
       AppButton {
         anchors.horizontalCenter: parent.horizontalCenter
         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 {
         anchors.horizontalCenter: parent.horizontalCenter
         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 {
       id: example1
       // ...      
     } // Example 1

     // 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 {
       id: messageText
       anchors.top: example1.bottom
       anchors.horizontalCenter: parent.horizontalCenter
       anchors.topMargin: dp(16)
       text: "Custom QML Type Message:\n" + typeFromCpp.message
       horizontalAlignment: AppText.AlignHCenter
     }
   }

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 {
  anchors.top: messageText.bottom
  anchors.horizontalCenter: parent.horizontalCenter
  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.

CES2018 – A great year coming for the automotive digitalization

CES 2018 was again a step forward in digitalization of automotive and Qt was more strongly presented than ever before (see our event page, listing some of the demos). The major trends of the event were even bigger screens, an increasing number and variety of different screens, and further integration of digital assistants. One of the less publicly visible items was the rollout of solutions for functional safety in digital clusters. On the floor, you couldn’t miss the number of electric bike concepts from very different manufacturers. It was our pleasure to demonstrate all the hot topics in our demos too. Surprisingly, the most commented on demo was not the great digital cockpit or fancy cluster with its 3d graphics, but the low-end e-bike demo – “how on earth is the UI so fluid without any acceleration?” It was the true proof of concept. You can see the details and the story behind the demo here: https://youtu.be/HoHE7tbsUMw.

 

Our partners were again strongly presented at CES 2018. As typical hardware and OS vendors were actively promoting the support for our technology with nice “Built with Qt” stickers and onscreen implementations. Some experts were even able to spot the hidden gems, i.e. implementations without the logo. The “Built with Qt” solutions presented ranged from technology demonstrations and concept cockpits to production-ready cars. The best examples you can find by looking at the QtProject Twitter account (https://twitter.com/qtproject). Based on the quick poll with Qt participants, no clear winner demo was awarded. Personally, I would like to test the Aston Martin with the Qt cockpit demoed by QNX Software Company.

QNX Aston Marting

 

It is clear that the new MBUX is the industry benchmark in terms of both technical and user experience. Also, we were asked by multiple customers how it  has been done and which technologies were used. Furthermore, the following week has just made the voice stronger – the whole industry is seeing MBUX as the new benchmark. Fortunately, the Qt strengths resonate well with it. We have a toolchain covering both 2D and 3D UI-designs, Qt making collaboration of designers and developers very iterative and the ecosystem is widespread with a variety of solutions available. We are looking forward to the automotive year of 2018 with great concepts from all continents. It is less than 360 days to CES 2019!

The post CES2018 – A great year coming for the automotive digitalization appeared first on Qt Blog.

Release 2.15.0: Upgrade to Qt 5.10 & Qt Creator 4.5 | Firebase Data Structures and Queries & Many Improvements

V-Play 2.15.0 adds support for Qt 5.10 and the latest Qt Creator 4.5. Qt 5.10 comes with many great features like Imagine Style for Qt Quick Controls 2 or language improvements for QML. Qt Creator 4.5 adds a new File System Navigation Tree and better support of platform tools. This update also improves the V-Play Firebase components for complex data structures and queries.

V-Play 2.15.0 Improvements

V-Play is now compatible with Qt 5.10 and Qt Creator 4.5. See later parts of this post for the highlights. V-Play Release 2.15.0 also includes many engine improvements:

Patch for Qt 5.10 QtGraphicalEffects Issue on iOS

Qt 5.10 is available for a while and offers many new features. But there were also some issues that prevented us from providing the update faster. For example, the release of Qt 5.10 introduced a QtGraphicalEffects issue on iOS. Thus, it is not possible to use graphical effects on iOS with Qt 5.10 at the moment.

This is a major issue for all mobile developers, so we didn’t release Qt 5.10 for V-Play until we had a fix ready. We took the time to prepare a patch, which is part of this V-Play update now. It allows you to keep working with QtGraphicalEffects on iOS with Qt 5.10. You can always count on V-Play to ship stable Qt builds for mobile development.

Note: Qt 5.10 also changes the minimum deployment target for iOS to iOS 10.0. Older versions are no longer supported by Qt.

Use Firebase Queries and Data Structures

The Firebase Plugin now supports working with complex data structures and queries. Apart from primitive data types, you can now read and write nested objects and arrays:

 FirebaseDatabase {
   id: firebaseDb

   Component.onCompleted: getValue("public/path/to/my/object")

   onReadCompleted: {
     if(success) {
       // parameter "value" can be a nested object/array, as read from your database
       console.debug("Read value " + value.subarray[3].subproperty.text)
     }
   }
 }

This allows you to save and load full data records of your application with a single call from QML. The update also introduces support for queries, with the optional parameter queryProperties. You can use this feature to retrieve your data sorted or filtered by custom conditions:

 FirebaseDatabase {
   id: firebaseDb

   Component.onCompleted: {
     //use query parameter:
     firebaseDb.getValue("public/bigqueryobject", {
                       orderByKey: true,  //order by key before limiting
                       startAt: "c",      //return only keys alphabetically after "c"
                       endAt: "m",        //return only keys alphabetically before "m"
                       limitToFirst: 5,   //return only first 5 sub-keys
                     })
   }
 }

The following example shows how to store data objects of a QML list with Firebase. The demo queries and displays only the twenty most recent entries of the list:

import VPlayApps 1.0
import VPlayPlugins 1.0
import QtQuick 2.0

App {
  readonly property int maxListEntries: 20
  property int numListEntries
  property bool loading: false

  FirebaseDatabase {
    id: firebaseDb

    //load total number of entries to compute index of next element
    realtimeValueKeys: ["public/numListEntries"]
    onRealtimeValueChanged: if(success && key === "numListEntries") numListEntries = value

    //load data on startup
    onPluginLoaded: loadData()
    onReadCompleted: {
      if(success) {
        //display DB data in ListView
        listView.model = value
      }
      loading = false
    }

    //refresh data directly from DB after saving
    onWriteCompleted: if(success) loadData()
  }

  Page {
    AppListView {
      id: listView

      anchors.left: parent.left
      anchors.right: parent.right
      anchors.top: parent.top
      anchors.bottom: actionBar.top
      anchors.topMargin: Theme.statusBarHeight

      delegate: SimpleRow {}

      model: [
        { text: "Loading data from database..." }
      ]
    }

    Flow {
      id: actionBar

      anchors.left: parent.left
      anchors.right: parent.right
      anchors.bottom: parent.bottom
      spacing: dp(12)

      AppButton {
        text: "Add new item"
        onClicked: addItem()
        enabled: !loading
      }

      AppActivityIndicator {
        visible: loading
      }
    }
  } // Page

  function loadData() {
    loading = true

    //load the last X entries, ordered by timestamp property
    firebaseDb.getValue("public/listEntries", {
                          limitToLast: maxListEntries,
                          orderByChild: "timestamp"
                        })
  }

  function addItem() {
    loading = true

    //add new DB item with timestamp and text
    var date = new Date()
    var timestamp = date.getTime()
    var text = "Item created at " + date.toString()

    var dbItem = { timestamp: timestamp, text: text }
    var index = numListEntries

    //using numbers as sub-keys makes the DB store data as an array
    firebaseDb.setValue("public/listEntries/" + index, dbItem)

    //keep track of total number of entries
    firebaseDb.setValue("public/numListEntries", numListEntries + 1)
  }
} // App

The update also brings more improvements and fixes for the Firebase Plugin. For example, you can access logged in user’s token or disable on-disk caching. To try the Firebase Plugin and test new features, please see the updated PluginDemo source on GitHub:

GitHub - V-Play Plugin Demo

New V-Play Live Client and Store App for iOS and Android

V-Play 2.15.0 comes with a reworked V-Play Live Client and Server. The updated Live Client supports all new features and components.

v-play-live-code-change-reload-windows-android-ios

It also adds many smaller improvements and fixes. For example, you can now choose whether to show the V-Play Live Client window on top of other open windows. You can do this with a setting in the Live Server application:

V-Play Live Client Stay-On-Top Toggle

The updated Live Client also comes with improved QML-error handling and logging capabilities. It now shows error log output on the error screen within the client window.

V-Play Live Client Error Screen Log Output

There’s also a new V-Play Live version available for you on the iOS App Store. It includes all the latest features, so make sure to get the updated app to be fully compatible with current version of V-Play Engine and the Live Server. You can download the app for iOS and Android here:

App Store Google_Play_Badge-1

Updated V-Play Sample Launcher with Qt World Summit Demo

This release also updates the V-Play Sample Launcher that comes with the V-Play SDK. It offers quick access to all V-Play demos and examples. The Sample Launcher now also features the new Qt World Summit app demo:

V-Play Sample Launcher with Qt World Summit Demo

The demo shows many additions like the SocialView components or improved navigation features. The demo is also available for you on GitHub:

GitHub - Qt World Summit 2017 app

More Improvements and Fixes

V-Play 2.15.0 comes with many other improvements, like better icon support for PictureViewer and PullToRefreshHandler.

V-Play 2.15.0 New PullToRefershHandler Icons

It also includes fixes for V-Play Multiplayer, Navigation Components and SyncedStore. For an overview of all changes, make sure to see the changelog here.

Qt 5.10 Improvements for Mobile App Development

Imagine Style, Fusion Style and Improved Qt Quick Controls

Qt 5.10 brings many additions for mobile app development, especially for Qt Quick Controls 2. Most prominent is the introduction of two new styles: Imagine style (left) and Fusion style (right):

Qt 5.10 Quick Controls Imagine Style and Fusion Style

Imagine style is an image-based style. You can now import your assets from Photoshop, which makes working with designers a lot easier. Create a custom look and feel simply by replacing the used images of the style. Fusion style gives a platform agnostic, desktop-oriented look and feel.

The update also introduces new types like Action, ActionGroup and MenuBar. It also adds many improvements for existing Quick Controls. For example, better icon support with new icon properties for AbstractButton.

Note: The V-Play AppTabButton type can no longer provide an icon property, as this would interfere with the Qt additions. So if you use the AppTabButton component and the icon property, rename it to tabIcon to have the same functionality like before this update.

There are also many minor changes, like the possibility to load ETC1 and ETC2 compressed textures, multisampling support for layers and some more properties to tune font handling.

QML Support for Enum and InstanceOf Type Checks

Qt 5.10 also brings some interesting language improvements for QML. First of all, it is now possible use enum properties in QML. Up until now, this was only possible with C++ types.

// MyText.qml
import QtQuick 2.0

Text {
  enum MyEnum {
    Normal,
    Heading
  }
    
  property int textType: MyText.MyEnum.Normal
    
  font.bold: textType == MyText.MyEnum.Heading
  font.pixelSize: textType == MyText.MyEnum.Heading ? 24 : 12
}

// Main.qml
import VPlayApps 1.0

App {
  MyText {
    textType: MyText.MyEnum.Heading
    text: "I'm a headline."
  }
}

Using enums for your types will help to better structure your QML code and make it more readable. Another improvement is the possibility to use instanceOf for checking QML types at runtime.

import VPlayApps 1.0
import QtQuick 2.0

App {
 // two QML items, used for type checking
 Item { id: testItem }
 Rectangle { id: testRect }

 // function to check wheter an item is a Rectangle
 function isRectangle(item) {
   return item instanceof Rectangle
 }

 // type check example
 Component.onCompleted: {
   console.log("testItem is Rectangle? "+isRectangle(testItem))
   console.log("testRect is Rectangle? "+isRectangle(testRect))
 }
}

This comes in handy when you create QML types at runtime. It is also useful to check types when iterating the QML tree or working with child items of a container.

Qt 5.10 Tech Preview: Pointer Handlers

The next big feature for Qt Quick are the new pointer handlers. Pointer handlers will improve handling complex multi-touch scenarios in the future. Instead of using the Mouse- and TouchArea types, you can now attach handlers for different pointer events.

import VPlayApps 1.0
import QtQuick 2.0
import Qt.labs.handlers 1.0

App {
 Rectangle {
   width: dp(100)
   height: dp(100)
  
   // handle touch or mouse-clicks
   TapHandler {
     onTapped: console.log("Item clicked")
   }
   // make the item rotate- and zoom-able with two-finger gestures
   PinchHandler { }
 }
}

Support for the pointer handler types is still in technology preview. So keep in mind that all types and properties will see bigger changes with the next Qt versions.

Qt 3D Improvements and Qt 3D Studio

The new Qt version extends the Qt 3D capabilities with many features. For example, support for Shader graphs and the technology preview of a skeletal animation system. There’s also a new Scene2D type, which simplifies embedding Qt 3D content in a Qt Quick Scene. It covers most of the main required features then. The focus for Qt 3D is thus moving to improve performance and memory consumption.

Qt 3D Studio is a graphical editor used to create 3D user interfaces. It consists of both a runtime component that is run in your application and a graphical design tool to design and create the UI. While the tool is a standalone application, the runtime can easily be integrated with the rest of Qt.

Qt 5.10 Qt 3D Studio

The runtime and the 3D Studio application are both available under commercial and GPL licensing. For more information about Qt 3D Studio, please have a look at the this post.

Place Custom Shaped Items in Your Scene

Qt Quick also gained a plugin that allows placing custom shaped items into the scene. You no longer require to work with QQuickPaintedItem or the Canvas type to create custom shapes.

V-Play 2.15 - Qt 5.10 Custom Shaped Scene Items

You can now use the new Shape Quick Item, which is backed by either actual geometry or a vendor-specific GPU accelerated path rendering approach. The main benefits are:

  • There is no rasterization involved. This allows shapes that span a large area of high-resolution screens and good-looking animations.
  • The API is fully declarative and all properties can be bound to in QML expressions, or animated using the usual tools of Qt Quick.
  • There are multiple rendering implementations under the hood. For example, a different renderer for NVIDIA GPUs takes advantages of certain OpenGL extensions. Other optimized renderers can thus also be added in the future.

Have a look at the blog post and documentation for more details.

Qt 5.10 also adds many other improvements and fixes for e.g. Qt Core, Qt Widgets or Embedded Systems. Also note that with Qt 5.10, the Qt Networking support for OAuth1 & 2 and Qt Speech features matured into a stable version. They are no longer in tech preview now. See the official release blog for more information. A list of all new features in Qt 5.10 can be found here.

Qt Creator 4.5 Support

The new version includes several UI improvements and better support of platform-specific tools. One of the bigger UI changes is the new File System Navigation Tree.

New File System Navigation Tree

The File System navigation pane is a lot more useful now. It shows a file system tree, where you can select the root directory from a list of useful folders:

  • The “computer” root
  • Your home directory
  • Your default projects directory
  • The base directories of all the projects you have open in Qt Creator

Qt Creator 4.5 File System Navigation Tree

Improved IDE Support for Android

The package manager within Android SDK is no longer available since Android build tools version 25.3.0. There is no UI tool available to manage the installed packages without Android Studio. Because of that, Qt Creator now comes with an own package manager for Android.

Qt Creator 4.5 Android Package Manager

Note: The command line tool of Android SDK cannot update packages on Windows, and fails with JDK 9. This applies to Qt Creator as well, as it depends on the tool. The package manager UI for Android is thus not usable on Windows until a new Android build tools version fixes these issues.

Qt Creator now also provides better information about problems with the installed SDK. For example for missing components or unmet version requirements.

More Additions

Qt Creator 4.5 also comes with better support of latest platform tools for iOS. It fixes the mechanism for switching between iOS Simulator device types with XCode 9.

For Windows, the detection of Visual Studio Build Tools 2017 is also fixed now. For more information about Qt Creator 4.5 see the official release blog.

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

v-play-2-14-2-how-to-use-vplay-plugins-with-live-reloading

Release 2.14.2: Live Code Reloading with Native Cross-Platform Plugins

v-play-2-14-1-live-reloading-windows-mac-linux-ios-android-qt

Release 2.14.1: Update to Qt 5.9.3 | Use Live Code Reloading on macOS and Linux

v-play-live-reloading-windows-mac-linux-ios-android-qt

Release 2.14.0: Live Code Reloading for Desktop, iOS & Android

 

feature

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

The post Release 2.15.0: Upgrade to Qt 5.10 & Qt Creator 4.5 | Firebase Data Structures and Queries & Many Improvements appeared first on V-Play Engine.

Qt in Visual Studio: A New Approach Based on MSBuild

As mentioned in a previous post, we have been working on a new official release of the Qt Visual Studio Tools. Ahead of this release, we would like to present some key changes and what impact they will have in usability and performance. In this post, we describe a new approach to the integration of the Qt tools moc, rcc and uic, both in the build process and at design time. In a follow-up post we will then discuss how these and other modifications contribute to an improvement in performance.

Custom Build Tools

Integrating external/third-party tools in Visual Studio has traditionally been accomplished by means of “Custom Build” steps associated to files in the project. The files could be, for example, headers containing Qt macros which must be processed by moc to generate the corresponding meta-object code. In this case, each header file is labeled as a custom build item and will have a custom build property page:

custom_build_step_property_page

This approach has some disadvantages:

“In older versions of Visual C++, you can specify, for a specific file, a custom command that gets executed before the C++ compilation step. This functionality, called Custom Build Steps, has some limitations when working with large projects and complex external tools. You cannot set up a custom build command to be run on all files of a particular type. Also, just for using an external application as a custom build step, you need to have extended knowledge of the configuration flags available on the command line.”
https://msdn.microsoft.com/en-us/library/aa730877(v=vs.80).aspx

Unlike the tools shipped with Visual Studio, such as the compiler or the linker, which have their own property pages, custom build steps are limited to a single text field where the path and arguments to the external tool must be specified. Also, as noted, a custom build step cannot be associated to a group of files – such as: “all headers containing Qt macros” – even though it would be possible to have only a single, global set of properties at project level. Each file must have its own custom build step information, which will be stored independently in the project file, regardless of repetition. This can lead to performance issues with large projects that make extensive use of custom build tools, as is the case with Qt projects.

MSBuild and Visual C++

In more recent versions of Visual Studio, MSBuild has become the underlying build engine for Visual C++. The content of C++ project files (*.vcxproj) is formatted according to the MSBuild XML schema and the build process is organized into MSBuild targets and tasks. Built-in tools, like the compiler and the linker, are parameterized through definitions – called “Rules” in Visual Studio-speak – which include the set of properties associated to a particular item type (e.g. C++ source files). The syntax of rule definitions also follows the MSBuild XML schema.

As an alternative to custom build steps, an external tool can be integrated into the build process by providing specialized MSBuild rules and targets. Instead of having to rely on the pre-defined behavior of the custom build mechanism, with this alternative approach it is possible to control the way the external tool is invoked using the full expressiveness of MSBuild. Also, by defining a rule for the external tool, project files can then be labeled as inputs to that tool rather than as generic custom build items. Instead of providing just one text field for the command line, Visual Studio will be able to provide those files with a property page specific to the external tool.

Qt and MSBuild

The new release of the Qt Visual Studio Tools will include MSBuild rules and targets specific to moc, rcc and uic (Qt/MSBuild for short). It will be possible, for example, to label header files as moc inputs. The property page that Visual Studio will display for these files will be specific to moc, and will contain fields covering all the options of that tool (the same will also apply for rcc and uic). As with internal Visual Studio tools like the C++ compiler, properties can be defined either for specific files or globally at project level:

moc_property_page_at_project_level

Projects created with the new version of the Visual Studio Tools will use Qt/MSBuild instead of custom build tools, and it will be possible to convert custom build tools in older projects. This conversion is not mandatory; the new version of the VS Tools will still work with custom build tools as before. When importing .pro files, the conversion of custom build tools to Qt/MSBuild will automatically take place.

The XML files with the Qt-specific rules and targets will be included in the VS Tools installation package and will be available to anyone that installs it. There is, however, no dependency to the VS Tools. Sharing a project that uses Qt/MSBuild (for example, with someone that does not have the VS Tools installed) will just require that the corresponding XML files be copied together with the project files.

The full expressiveness of MSBuild provides access to new possibilities which were not available with custom build tools. For instance, it is now possible to run moc, rcc and uic in parallel processes instead of having to go through every file in sequence, which was the only option with custom build tools. This feature is implemented in Qt/MSBuild using two targets. The first target goes through all input files, generates the command line to run for each file and adds it to a list of work to do. Another target then reads from this list and spawns the corresponding processes. The result, as expected, is a visible decrease in processing time:

parallel_execution_of_qt_tools

Another important benefit of using MSBuild is the possibility to directly influence the build process, including what project items are processed and with what tools. Inside an MSBuild target, it’s possible to add new items to the build and choose with which tools to process them. The Qt/MSBuild targets make use of this feature, for instance, to handle C++ source files containing Qt class definitions. These files are manually added to the project labeled as moc inputs, and are then dynamically reintroduced into the build process as inputs to the C++ compiler.

Furthermore, by using the dynamic source feature of MSBuild, source files generated by the Qt tools can be added “on-the-fly” to the C++ compilation during the build process. As such, there will be no need to include generated files in the project. This has a positive effect on the performance of the VS Tools, which will be part of the discussion in the next blog post.

Future Improvements

The new approach to the integration of moc, rcc and uic may potentially break some use cases where a file needs to be processed by a Qt tool and by some other third-party tool. This type of use case is currently possible given that the custom build is a generic mechanism that can be used to invoke any number of commands. Taking the example of a header file containing Qt macros, there is no guarantee that only moc will be called in that file’s custom build step. The conversion of custom build to Qt/MSBuild will only consider calls to moc, rcc and uic; all other commands in the custom build steps will be ignored.

One such use case concerns the integration of the tool IncrediBuild. If this tool is installed, when importing a .pro file using the current version of the VS Tools the custom build steps will contain additional instructions for IncrediBuild to run moc, rcc and uic in parallel/distributed processes. For the upcoming release, this integration will no longer be supported. The parallel execution of Qt tools will still work when using IncrediBuild but only on the local machine (built-in tools like the C++ compiler will still be able to run on distributed processes). A specific fix for the integration with IncrediBuild will be available in a later version of the VS Tools. As a generic solution to this issue of additional commands to run together with the Qt tools, we could consider allowing those commands to be given as pre- or post-events in the moc, rcc and uic property pages.

Wrap-Up

We have presented the outline of a new approach to the way moc, rcc and uic are integrated in Visual Studio. This new approach provides a design time experience and build time integration identical to that of built-in tools. In a follow-up post, we will discuss what impact these and other changes to the VS Tools will have in terms of performance. Hopefully, users will find that, with these changes, developing with Qt on Visual Studio will become even more productive.

The post Qt in Visual Studio: A New Approach Based on MSBuild appeared first on Qt Blog.

Nailing 13 signal and slot mistakes with clazy 1.3

Today I want to share 13 mistakes regarding signals, slots and connect statements and how to find them at compile time with clazy, our open-source static-analyzer for Qt.

Clazy is a compiler plugin which generates warnings related to Qt. You can read more about it in our previous blog posts:

Today's instalment is exclusively about signal/slots, since that's what the newest 1.3 release focused on.

So let's start the walkthrough! For completeness a few older checks are also included, as they belong to this topic.

1. connect-non-signal

This check warns when connecting a non-signal to something. For example connecting two slots together:

[code lang="cpp"] connect(obj, &MyObj::mySlot, &MyObj::mySlot2);
warning: MyObj::mySlot is not a signal [-Wclazy-connect-non-signal]
[/code]

The above doesn't make sense, as connect statements should reference at least 1 signal. However, it compiles just fine, since it's valid C++. With clazy your compiler will get Qt semantics and complain about this mistake.

2. lambda-in-connect

Warns when a lambda inside a connect() captures local variables by reference.

Example:

[code lang="cpp"]
void myFunction()
{
int localVar = ...;

// program will crash when signal is emitted!
connect(m_object, &MyObj::mySignal, [&localVar] { ... });
}
[/code]

This usually results in a crash as the lambda might get called after the captured variable went out of scope.

3. connect-3arg-lambda

Warns when using the 3 argument connect() that takes a lambda. The recommendation is to use the overload with 4 arguments, taking a context object to control the connection's lifetime.

It's very common to use lambdas to connect signals to slots with different number of arguments:

[code lang="cpp"]
connect(m_widget, &MyWidget::textChanged, [this] (const QString &text) {
m_receiver->update(text, false);
});
[/code]

But the above code will cause a crash if the signal is emitted after m_receiver is deleted. To avoid this, just pass a context object as 3rd argument:

[code lang="cpp"]
connect(m_widget, &MyWidget::textChanged, m_receiver,
[this] (const QString &text) { (....) });
[/code]

4. lambda-unique-connection

Finds usages of Qt::UniqueConnection where the receiver is a functor, lambda or global function. As stated by the Qt documentation, this connect() overload does not support Qt::UniqueConnection.

5. thread-with-slots

Warns for any slot present in QThread derived classes. Although not necessarily a bug, it's usually a code smell, as these slots will run in the thread where the QThread QObject lives and not in the thread itself. The best practice is usually to use worker objects, as illustrated here.

6. old-style-connect

Finds connect() statements still using the old SIGNAL()/SLOT() syntax. The Qt 5 pointer-to-member syntax allows you to catch errors at compile-time rather than runtime. A fixit is included for automatically rewriting your connects to the new form.

7. connect-not-normalized

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

Example:

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

See QMetaObject::normalizedSignature() for more information.

8. overridden-signal

Warns when overriding signals in derived classes. APIs with overridden signals are hard to use, unexpected and bug-prone.
To make it worse, Qt even allows you to override a signal with a non-signal, and vice-versa.

To avoid complaining about some benign-cases, clazy won't warn when both signals have different signatures.

9. virtual-signal

This check warns when a signal is virtual.
Virtual signals make it very hard to read connect statements since they are unexpected.

moc also discourages their use by printing a non-fatal message at runtime:
Warning: Signals cannot be declared virtual

10. const-signal-or-slot

Warns when a signal or non-void slot is const.

This aims to prevent unintentionally marking a getter as slot, or connecting to the wrong method. For signals, it's just pointless to mark them as const.

Warns for the following cases:

  • non-void const method marked as slot
  • const method marked as signal
  • connecting to a method which isn't marked as slot, is const and returns non-void

For exposing methods to QML prefer either Q_PROPERTY or Q_INVOKABLE.

11. incorrect-emit

For readability purposes you should always use emit (or Q_EMIT) when calling a signal. Conversely, you should not use those macros when calling something other than a signal.

Clazy will warn if you forget to use emit (or Q_EMIT) or if you use them when you shouldn't.

12. connect-by-name

Warns when auto-connection slots are used. They're also known as "connect by name", an old and unpopular feature which shouldn't be used anymore.

These types of connections are very brittle, as a simple object rename would break your code.
In Qt 5 the pointer-to-member-function connect syntax is prefered as it catches errors at compile-time.

This check simply warns for any slot named like on_*_*, because even if you're not using .ui files this naming is misleading and not good for readability, as the reader would think you're using auto-connection.

13. qproperty-without-notify

Warns when a non-CONSTANT Q_PROPERTY is missing a NOTIFY signal.
Although this best practice has been popularized by QML, it's actually useful for any Q_PROPERTY, as any consumer of properties can make use of the notify, for example Gammaray.

Conclusion

Qt, or more specifically, moc, is very permissive in what it allows, either due to technical limitations, or simply the requirement to maintain source compatibility.
I'm of the opinion we should be more strict and only use a sub-set of what it allows, by following these guidelines and enforcing them with clazy, our open-source plugin for clang.
Some issues reported by clazy won't imply a bug in your code, but you should strive to have 0 warnings nevertheless. You'll sleep much better at night, specially on big codebases. continue reading

The post Nailing 13 signal and slot mistakes with clazy 1.3 appeared first on KDAB.