KDAB contributions to Qt 5.4

Qt 5.4 was released just last week! The new release comes right on schedule (following the 6-months development cycle of the Qt 5 series), and brings a huge number of new features.

KDAB engineers have contributed lots of code to Qt during the last few months. Once more, KDAB is the second largest contributor to Qt (the first being The Qt Company itself). The commit stream has been constant, as you can see in this graph showing the last 16 weeks:

Contributions to Qt by employer (excluding Digia), from here</a>

Contributions to Qt by employer (excluding Digia), from here

In this blog post I’ll show some of the notable features developed by KDAB engineers that you are going to find in Qt 5.4.

Qt WebChannel

The Qt WebChannel module has been introduced to fill the gap left when Qt switched from WebKit 1 (QWebView) to WebKit 2 (WebView in QML) and Blink (QtWebEngine). That is: the possibility of having QObject instances exposed in the JavaScript environment of a loaded page.

The ultimate cause of this lost feature is that modern HTML engines employ multiple processes for performance and security reasons, and therefore the same kind of deep integration that the WebKit Bridge made possible was not available any more.

The WebChannel brings back this awesome functionality, and it extends it even further — it is now possible to export QObjects to any remote browser, that is, not only the WebViews owned by the very same Qt application.

For more information, please refer to this blog post by my colleague Milian Wolff.

The Declarative State Machine Framework

Back in the day, Qt 4.6 introduced a State Machine Framework based on SCXML. It consisted of a few C++ classes to build state machines out of individual states and transitions, and had quite a nice feature set: it supported parallel states, final states, history states, guarded transitions and so on.

Unfortunately, writing state machines by hand requires a lot of boilerplate C++ code. For instance, in order to add a transition to a new state, we must create a new QState object, create a new transition object, and finally add the transition.

Ford Motor Company, in a technical partnership with KDAB, has generously contributed high-level QML wrappers for the C++ state machine. The new technology goes under the name of Declarative State Machine Framework; it uses QML as a Domain Specific Language (DSL) for writing declarative state machines, while being backed by the full C++ state machine framework.

DSM allows users to create state machines using QML, therefore removing the need of boilerplate code, resulting in a nice and compact representation for state machines.

What’s more, it also allows removing the imperative bits from the state machine (that is, which properties should be updated when entering a state); it instead enables any given QML element to bind its property to whether the state machine is in a state or not.

Please refer to the module documentation for more information, as well as the short talk by my colleague Kevin Funk from this year’s Qt Developer Days.

QNX co-maintainership

Due to KDAB’s sustained efforts into supporting QNX, we’re very pleased to hear that my colleague Rafael Roquetto has been nominated co-maintainer of the QNX support in Qt. He’s going to join the ranks with our colleague Bogdan Vatra, maintainer of the Android support. Congratulations, Rafael!

Other contributions

In no particular order:

qmllint

qmllint is a syntax checker for QML files. You can therefore run it on your QML files before shipping them with your application, or add a qmllint step to your CI system / SCM hooks. If you want to know more, please refer to this blog post by my colleague Sérgio Martins.

New hooking system for tooling

Qt has always had a number of private entry points that were supposed to be used by debugging/profiling tools. Unfortunately, due to aggressive compiler optimizations, those hooks were almost always compiled out in release builds, and therefore their usage on any platform but Linux/GCC was extremely problematic.

KDAB’s Senior Engineer Volker Krause developed a solution for this problem, which can be found in Qt 5.4.

The main user of this feature is of course GammaRay, one of the KDAB’s flagship products. GammaRay is a free software solution that provides high level debugging for Qt, allowing the developer to inspect individual subsystems of any complex application.

Lots of bugfixes

Working on real projects, we do know that code does not always behave as advertised. At the same time, we strive to make Qt the best product for cross-platform, high-performance application development.

Therefore, it should not be a surprise that KDAB engineers fixed over 50 reported bugs between Qt 5.3 and Qt 5.4 (and, of course, fixed even more problems which didn’t even have an associated bug report!). Only a few weeks ago KDAB launched a new service, FixMyQtBug, to help companies building products using Qt which are struggling against upstream bugs; our skills and dedication show that we indeed are the experts when it comes to Qt, and we are willing to fix your Qt bugs as well.

The post KDAB contributions to Qt 5.4 appeared first on KDAB.

Overview of Qt3D 2.0 – Part 1

Introduction

Back in the days when Qt was owned by Nokia, a development team in Brisbane had the idea of making it easy to incorporate 3D content into Qt applications. This happened around the time of the introduction of the QML language and technology stack, and so it was only natural that Qt3D should also have a QML based API in addition to the more traditional C++ interface like other frameworks within Qt.

Qt3D was released alongside Qt 4 and saw only relatively little use before Nokia decided to divest Qt to Digia. During this transition, the Qt development office in Brisbane was closed and unfortunately Qt3D never saw a release alongside Qt 5. This chain of events left the Qt3D code base without a maintainer and left to slowly bit rot.

With OpenGL taking a much more prominent position in Qt 5’s graphical stack — OpenGL is the underpinning of Qt Quick 2’s rendering power — and with OpenGL becoming a much more common part of customer projects, KDAB decided that it would be good for us and for the Qt community at large if we took over maintainership and development of the Qt3D module. To this end, several KDAB engineers have been working hard to bring Qt3D back to life and moreover to make it competitive to other modern 3D frameworks.

This article is the first in a series that will cover the capabilities, APIs, and implementation of Qt3D in detail. Future articles will cover how to use the API in various ways from basic to advanced with a series of walked examples. For now, we will begin in this article with a high-level overview of the design goals of Qt3D; some of the challenges we faced; how we have solved them; what remains to be done before we can release Qt3D 2.0; and what the future may bring beyond Qt3D 2.0.

What Should Qt3D Do?

When asked what a 3D framework such as Qt3D should actually do, most people unfamiliar with 3D rendering simply say something along the lines of “I want to be able to draw 3D shapes and move them around and move the camera”. This is, of course, a sensible baseline, but when pressed further you get back wishes that typically include the following kinds of things:

  • 2D and 3D
  • Meshes
  • Materials
  • Shadows

Then, when you move on and ask the next target group, those who already know about the intricacies of 3D rendering, you get back some more technical terms such as:

That is already a fairly complex set of feature requests, but the real killer is that last entry which translates into ‘I want to be able to configure the renderer in ways you haven’t thought of’. Given that Qt3D 1.0 offered both C++ and QML APIs this is something that we wished to continue to support, but when taken together with wanting to have a fully configurable renderer this led to quite a challenge. In the end, this has resulted in something called the framegraph.

Framegraph vs Scenegraph

A scenegraph is a data-driven description of what to render.
The framegraph is a data-driven description of how to render.

Using a data-driven description in the framegraph allows us to choose between a simple forward renderer; or including a z-fill pass; or using a deferred renderer; when to render any transparent objects etc. Also, since this is all configured purely from data, it is very easy to modify even dynamically at runtime. All without touching any C++ code at all!

Once you move beyond the essentials of getting some 3D content on to the screen, it becomes apparent that people also want to do a lot of other things related to the 3D objects. The list is extensive and wide ranging but very often includes requests like:

This is obviously a tall order, and one that we couldn’t possibly hope to satisfy out of the box with the limited resources available. However, it is clear, that in order to support these features in the future, we needed to do some ground work now to architect Qt3D 2.0 to be extensible and flexible enough to act as a host for such extensions. The work around this topic took a lot of effort and several aborted prototypes before we settled on the current design. We will introduce the resulting architecture later and then cover it in more detail in an upcoming article.

Beyond the above short and long term feature goals, we also wanted to make Qt3D perform well and scale up with the number of available CPU cores. This is important given how modern hardware is improving performance — by increasing the numbers of cores rather than base clock speed. Also, when analysing the above features we can intuitively hope that utilising multiple cores will work quite naturally since many tasks are independent of each other. For example, the operations performed by a path finding module will not overlap strongly with the tasks performed by a renderer (except maybe for rendering some debug info or statistics).

Overview of the Qt3D 2.0 Architecture

The above set of requirements turned out to be quite a thorny problem, or rather a whole set of them. Fortunately, we think we have found solutions to most of them and the remaining challenges look achievable.

For the purposes of discussion, let’s start at the high-level and consider how to implement a framework that is extensible enough to deal with not just rendering but also all of the other features plus more that we haven’t though of.

At its heart, Qt3D is all about simulating objects in near-realtime, and then very likely then rendering the state of those objects onto the screen somehow. Let’s break that down and start with asking the question: ‘What do we mean by an object?’

Space-invadersOf course in such a simulation system there are likely to be numerous types of object. If we consider a concrete example this will help to shed some light on the kinds of objects we may see. Let’s consider something simple, like a game of Space Invaders. Of course, real-world systems are likely to be much more complex but this will suffice to highlight some issues. Let’s begin by enumerating some typical object types that might be found in an implementation of Space Invaders:

  • The player’s ground cannon
  • The ground
  • The defensive blocks
  • The enemy space invader ships
  • The enemy boss flying saucer
  • Bullets shot from enemies and the player

In a traditional C++ design these types of object would very likely end up implemented as classes arranged in some kind of inheritance tree. Various branches in the inheritance tree may add additional functionality to the root class for features such as: “accepts user input”; “plays a sound”; “can be animated”; “collides with other objects”; “needs to be drawn on screen”.

I’m sure you can classify the types in our Space Invaders example against these pieces of functionality. However, designing an elegant inheritance tree for even such a simple example is not easy.

This approach and other variations on inheritance have a number of problems as we will discuss in a future article but includes:

  • Deep and wide inheritance hierarchies are difficult to understand, maintain and extend.
  • The inheritance taxonomy is set in stone at compile time.
  • Each level in the class inheritance tree can only classify upon a single criteria or axis.
  • Shared functionality tends to ‘bubble up’ the class hierarchy over time.
  • As library designers we can’t ever know all the things our users will want to do.

Anybody that has worked with deep and wide inheritance trees is likely to have found that unless you understand, and agree with, the taxonomy used by the original author, it can be difficult to extend them without having to resort to some ugly hacks to bend classes to our will.

For Qt3D, we have decided to largely forego inheritance and instead focus on aggregation as the means of imparting functionality onto an instance of an object. Specifically, for Qt3D we are using an Entity Component System (ECS). There are several possible implementation approaches for ECSs and we will discuss Qt3D’s implementation in detail in a later article but here’s a very brief overview to give you a flavour.

An Entity represents a simulated object but by itself is devoid of any specific behaviour or characteristics. Additional behaviour can be grafted on to an entity by having the entity aggregate one or more Components. A component is a vertical slice of behaviour of an object type.

What does that mean? Well, it means that a component is some piece of behaviour or functionality in the vein of those we described for the objects in our Space Invaders example. The ground in that example would be an Entity with a Component attached that tells the system that it needs rendering and how to render it; An enemy space invader would be an Entity with Components attached that cause them to be rendered (like the ground), but also that they emit sounds, can be collided with, are animated and are controlled by a simple AI; The player object would have mostly similar components to the enemy space invader, except that it would not have the AI component and in its place would have an input component to allow the player to move the object around and to fire bullets.

ecs-2

On the back-end of Qt3D we implement the System part of the ECS paradigm in the form of so-called Aspects. An aspect implements the particular vertical slice of functionality imbued to entities by a combination of one or more of their aggregated components. As a concrete example of this, the renderer aspect, looks for entities that have mesh, material and optionally transformation components. If it finds such an entity, the renderer knows how to take that data and draw something nice from it. If an entity doesn’t have those components then the renderer aspect ignores it.

Qt3D is an Entity-Component-System

Qt3D builds custom Entities by aggregating Components that impart additional capabilities. The Qt3D engine uses Aspects to process and update entities with specific components.

Similarly, a physics aspect would look for entities that have some kind of collision volume component and another component that specifies other properties needed by such simulations like mass, coefficient of friction etc. An entity that emits sound would have a component that says it is a sound emitter along with when and which sounds to play.

A very nice feature of the ECS is that because they use aggregation rather than inheritance, we can dynamically change how an object behaves at runtime simply by adding or removing components. Want your player to suddenly be able to run through walls after gobbling a power-up? No problem. Just temporarily remove that entity’s collision volume component. Then when the power-up times out, add the collision volume back in again. There is no need to make a special one-off subclass for PlayerThatCanSometimesWalkThroughWalls.

Hopefully that gives enough of an indication of the flexibility of Entity Component Systems to let you see why we chose it as the basis of the architecture in Qt3D. Within Qt3D the ECS is implemented according to the following simple class hierarchy.

Qt3D’s ‘base class’ is QNode which is a very simple subclass of QObject. QNode adds to QObject the ability to automatically communicate property changes through to aspects and also an ID that is unique throughout the application. As we will see in a future article, the aspects live and work in additional threads and QNode massively simplifies the tasks of getting data between the user-facing objects and the aspects. Typically, subclasses of QNode provide additional supporting data that is then referenced by components. For example a QShaderProgram specifies the GLSL code to be used when rendering a set of entities.

ecs-1

Components in Qt3D are implemented by subclassing QComponent and adding in any data necessary for the corresponding aspect to do its work. For example, the Mesh component is used by the renderer aspect to retrieve the per-vertex data that should be sent down the OpenGL pipeline.

Finally, QEntity is simply an object that can aggregate zero or more QComponent’s as described above.

To add a brand new piece of functionality to Qt3D, either as part of Qt or specific to your own applications, and which can take advantage of the multi-threaded back-end consists of:

  • Identify and implement any needed components and supporting data
  • Register those components with the QML engine (only if you wish to use the QML API)
  • Subclass QAbstractAspect and implement your subsystems functionality.

Of course anything sounds easy when you say it fast enough, but after implementing the renderer aspect and also doing some investigations into additional aspects we’re pretty confident that this makes for a flexible and extensible API that, so far, satisfies the requirements of Qt3D.

Qt3D has a Task-Based Engine

Aspects in Qt3D get asked each frame for a set of tasks to execute along with dependencies between them. The tasks are distributed across all configured cores by a scheduler for improved performance.

Summary

We have seen that the needs of Qt3D extend far beyond implementing a simple forward-renderer exposed to QML. Rather, what is needed is a fully configurable renderer that allows to quickly implement any rendering pipeline that you need. Furthermore, Qt3D also provides a generic framework for near-realtime simulations beyond rendering. Qt3D is cleanly separated into a core and any number of aspects that can implement any functionality they wish. The aspects interact with components and entities to provide some slice of functionality. Examples of future possible aspects include: physics, audio, collision, AI, path finding.

In the next part of this series, we shall demonstrate how to use Qt3D and the renderer aspect to produce a custom shaded object and how to make it animate all from within QML.

trefoil-wireframe

The post Overview of Qt3D 2.0 – Part 1 appeared first on KDAB.

Rendering PDF Content with XpdfWidget

A consulting project I worked on recently needed to display an interactive PDF document in the style of Adobe Reader on a touchscreen device running embedded Linux using Qt and QML. I have been working with Qt for nearly ten years and had not come across this requirement before, so of course I turned to the Internet to see what was available and I came across this page, which lists all options available for dealing with PDF files from Qt.

Swift and Isode

Having been working on this behind the scenes for a while, we’ve got some good news. After years of quietly supporting Swift, Isode are now taking Swift formally into their product set. This means more developers working on Swift and the opportunity for more rapid development and advancement of the projects. In practical terms, we think the only obvious change externally is likely to be an increase in activity in the commit logs and improvements to the software, both of which have been becoming increasingly obvious in recent months as Isode’s been increasing support.

Some details about which you may care:

  • Isode’s a long-term producer of messaging and directory servers, including the M-Link XMPP server, has been the provider of commercial licenses for Swiften, was responsible for the port of Swiften to Java in the form of Stroke and is where Kev works for his day-job.
  • Kev’s going to manage the Swift projects within Isode.
  • Swift, Stroke et al. will be remaining open source, with commercial licensing and support available.
  • The project will continue to run in much the same way, with public code review systems etc.
  • We’ll still be accepting community-supplied patches
  • We’ll still be encouraging testing and feedback by the community
  • We think this is going to be an opportunity to make Swift better

We hope you’ll join us in our excitement for Swift’s future.

Qt 5.4 released


I am happy to announce that Qt 5.4 has been released today and is available for download from qt.io. Together with Qt 5.4, we have also released Qt Creator 3.3 and an update to Qt for device creation on embedded Linux and embedded Android.

But let’s start with Qt 5.4. One of the main focus areas of this Qt release has been around Web technologies and we have a lot of cool new things to offer there.

Renewed Web Story

HTML5 and Web technologies have become more and more important over the last years, and we have spent the last year developing a completely renewed Web offering for Qt. The Qt WebEngine module is the result of a long-term R&D project where we adopted the Chromium Web engine for use within Qt. With Qt 5.4, it is fully supported on the most used desktop and embedded platforms. Qt WebEngine provides you with an easy-to-use API to embed Web content in both Qt Widgets and Qt Quick based applications.

The new Qt WebChannel module provides a simple-to-use bridge between QML/C++ and HTML/Javascript. This enables the creation of hybrid applications that use both Qt and Web technologies. Communication between both sides happens by exposing QObjects in the Web context. The module works not only with Qt WebEngine, but also with any other browser engine that has support for Web sockets.

As a third component, Qt 5.4 introduces a Technology Preview of a new module called Qt WebView. The Qt WebView module offers a more limited API to embed the web browser that is native to the underlying operating system for use cases where the full Qt WebEngine isn’t needed, or where it can’t be used because of restrictions coming from the underlying OS. In Qt 5.4, the Qt WebView module supports iOS and Android.

Together with the Qt WebSockets module introduced in Qt 5.3, Qt now has great support for many of the latest Web technologies and makes interacting with Web content very easy. Qt WebEngine and Qt WebView make it very easy to embed HTML5, Qt WebChannel creates the communication channel between Qt and HTML5 that is required for hybrid applications, and Qt WebSockets allows for an easy communication between Qt and many Web services.

Qt 5.4 also still contains the older Qt WebKit module. Qt WebKit is still supported, but as of Qt 5.4 we consider it done, so no new functionality will be added to it. We are also planning to deprecate Qt WebKit in future releases, as the new Qt WebEngine provides what is needed. In most use cases, migrating from Qt WebKit to Qt WebEngine is rather straightforward. If you are starting a new project that requires web capabilities, we advise that you already start using Qt WebEngine.

Qt for WinRT | Completing our Cross-Platform Offering

The second big new feature of Qt 5.4 is the completion of our cross-platform story with the full support for Qt on Windows Runtime. Qt for Windows Runtime was already added as a supported Beta to Qt 5.3, and has now reached the state where it is a fully supported part of Qt. With Qt for Windows Runtime, you can create applications for the Windows Store, targeting both Windows Phone 8.1 and above as well as Windows 8.1 and newer.

This port completes our cross-platform story and we feel that Qt now supports all currently relevant desktop, embedded and mobile operating systems.

Graphics updates

Qt 5.4 brings also a lot of other new features and improvements. One focus are has been around graphics. With Qt 5.4, we now introduce better support for high-resolution displays for our desktop platforms. The support is still considered experimental in Qt 5.4, if you are interested, check out the overview documentation.

OpenGL support on Windows has been problematic in a few cases, since there aren’t always good drivers available. To help with this problem, Qt now has the capability to dynamically select the OpenGL implementation that is being used at application start-up time. Qt will now choose between using the native OpenGL driver, the ANGLE’s OpenGL ES 2.0 implementation that translates to DirectX or a pure Software rasterizer.

Qt Data Visualization has been updated to version 1.2 including additional features such as volume rendering and texture support for surface graphs and performance improvements. Qt Charts has now been updated to version 2.0 including better Qt 5 modularization, binary packages and minor improvements.

Other improvements on the graphics side is the new QOpenGLWidget class that replaces the old QGLWidget class from Qt 4 and allows us to deprecate the old Qt OpenGL module as all relevant functionality can now be found in Qt Gui. QOpenGLContext can now wrap existing native contexts. You can use the new QQuickRenderControl to render Qt Quick scenes into an offscreen buffer. For more details check out this blog post.

Finally, Qt 5.4 contains a technology preview of our new Qt Canvas3D module, that implements a WebGL like API for Qt Quick. This module makes it very easy to use Javascript code using WebGL within Qt Quick.

We have so many new things in Qt 5.4 that we have to list them all. Before you keep moving down the blog, check out our Qt 5.4 highlights video.

 

Other new features

A large amount of other new features have also found their way into Qt 5.4. I’ll just mention a few of them in this blog post.

Qt now supports Bluetooth Low Energy on Linux using BlueZ. Support for other platforms will come in later versions of Qt. Bluetooth LE makes it possible to communicate with many modern Bluetooth devices such as e.g. wearables.

On Android we now have native looking Qt Quick Controls, as well as smaller deployment packages and faster application startup times. For iOS and Mac OS X, we have now support for the latest operating system versions, XCode 6 and the new code signing style required to push applications into the App Store. We especially worked hard to fix all issues related to the new style on Mac OS X 10.10.

Qt Qml comes now with support for Qt State Machines through the new QtQml.StateMachine import, and Qt Core has gained a new QStorageInfo class giving you information about mounted devices and volumes.

Qt Quick Controls now also come with a brand new and great looking ‘flat style’ that can be used on all platforms.

Qt 5.4, also comes with a brand new version of Qt Creator, Qt Creator 3.3. For details on all the new things in there check out our separate blog post.

Qt for device creation

Today, we also release a new version of our development package for device creation. Here are some of the new features that are included in this release:

We now have preliminary support to run Qt Applications on Wayland using the Weston compositor on i.MX6 based devices, including support for Video and Qt WebEngine.

We added a new B2Qt Utils module that gives easy access to device-specific settings such as the display backlight, hostname or power state from both C++ and QML. The B2Qt Wi-Fi module is now officially supported and makes it easy to configure your Wi-Fi network.

Apart from these new features we have added a large amount of improvements:

  • eAndroid Qt Multimedia plugin update.
    • The implementation of Qt Multimedia for embedded Android has been refactored, resulting in a cleanly separated and easier maintained plugin for that platform.
  • SD Card Flashing Wizard for easier b2qt image deployment
    • Simple wizard for writing system image to SD card
    • Integrated into Qt Creator
  • BYOS (Build Your Own Stack) Improvements
    • Improved scripts for initializing and managing the Yocto build environment: Using repo tool for managing the numerous meta repositories needed for different devices.
  • eLinux: Camera support for i.MX6 devices
    • All necessary GStreamer plugins for using camera in Qt Quick applications are now integrated into reference device images
    • MIPI camera support added

With this version, we have also added new hardware reference platforms, including a low-end profile for the GPU-less Freescale Vybrid. The complete list of reference hardware supported by Qt for device creation can be found in the documentation.

Qt Quick without OpenGL

Another great new feature for our embedded customers is the new Qt Quick 2D Renderer module. This new commercial add-on allows using Qt Quick on embedded devices that have no OpenGL hardware acceleration. The new Qt Quick2DRenderer module can render most of Qt Quick using pure software rasterization or 2D hardware acceleration through e.g. DirectFB or Direct2D. The module support all of Qt Quick with the exception of OpenGL shaders and particles.

This enables the creation of Qt Quick based user interfaces with a modern look and feel on lower end devices than before. In addition, the ability to use the Qt Quick API across a device portfolio spanning devices both with and without OpenGL significantly reduces the amount of UI code you need to write and maintain. To showcase the Qt Quick 2D Renderer’s capabilities, we have added the Toradex Colibri VF50 and VF61 devices as new reference hardware to the Boot to Qt software stack, demonstrating our ability to run on the Freescale Vybrid SoCs.

Introduction of LGPL v3

As announced earlier, the open-source version for Qt 5.4 is also made available under the LGPLv3 license. The new licensing option allows us at The Qt Company to introduce more value-add components for the whole Qt ecosystem without making compromises on the business side. It also helps to protect 3rd party developers’ freedom from consumer device lock-down and prevents Tivoization as well as other misuse.

In Qt 5.4, a few modules are exclusively available under GPL/LGPLv3 or commercial license terms. These modules are the new Qt WebEngine and the Technology Previews ofQt WebView and Qt Canvas 3D. The Android style is only available under a commercial license or the LGPLv3. You can find more details here.

Thanks to the Qt Community

Qt 5.4 adds a lot of new functionality and improvements. Some of them would not have been possible without the help of the great community of companies and people that contribute to Qt and are not employees of The Qt Company.

While I can’t mention everybody here, I would like to still name a few. I’d like to thank our Qt Service Partner KDAB for continuously being the second biggest contributor to Qt, and in this release especially Milian Wolf for his work on Qt WebChannel. I’d also like to thank Orgad Shaneh from Audiocodes for his continuous help on and involvement with Qt Creator and Thiago Macieira from Intel for his long-term involvement. I’d also like to mention Brett Stottlemyer from Ford for contributing the new QML State Machine Framework and Ivan Komissarov for the new QStorageInfo class.

Make sure to try Qt 5.4, www.qt.io/download. Enjoy!

Qt Creator 3.3.0 released


We are happy to announce the Qt Creator 3.3.0 release today. This release comes with a great set of new features as well as a big amount of bug fixes.

I talked about many of the new features and improvements already in the beta release blog post. For today’s release, Alessandro locked himself in his office for a while and created this “What’s new in Qt Creator 3.3″ video!

Other features include support for the Gradle build system for Android development, a refactoring action for adopting the new connect style in Qt 5, BareMetal support for CMake projects, and an option to use the Qt Quick Compiler for your Qmake based QML projects. Please also see our change log for a more complete list of changes.

For users of the Professional or Enterprise edition, we added experimental support for running the Clang Static Analyzer on your projects, as a new tool in Analyze mode. The scene graph events category in the QML Profiler has been significantly improved and will now visualize the time ranges of all scene graph related events instead of showing them as a list of numbers. You can also see input events in the QML profiler now, in a separate category. In Qt Quick Designer we added direct editing of TabViews, and additional checks for form files (.ui.qml) as well as buttons for exporting form items for use in the implementation files.

Qt Creator 3.3.0 is part of the installers for Qt 5.4.0, which is also released today.

Both are now available for download on qt.io. Please post issues in our bug tracker. You also can find us on IRC on #qt-creator on irc.freenode.net, and on the Qt Creator mailing list.

Note: With Qt Creator 3.3 we drop support for compiling Qt Creator with Qt 4. The minimal required Qt version to compile Qt Creator itself is currently Qt 5.3.1. This does not affect compilation of your own projects, of course. We still support development of Qt 4-based applications with Qt Creator. If you want to use custom designer plugins in Qt Creator, you must make them compilable with Qt 5 as well, though.

Multi-process embedded systems with Qt for Device Creation and Wayland


With the Qt 5.4 update for Qt for Device Creation it is now possible – on certain embedded systems – to run Qt applications on top of a Wayland compositor by relying only on the provided reference images without any additional modifications. While the stable and supported approach remains eglfs, the lightweight platform plugin that allows running fullscreen Qt applications on top of EGL and fbdev with the best possible performance, those who do not require any of the enhanced tooling but need to have multiple GUI applications running on the same screen can start experimenting with a Wayland-based system already today.

In this post we will take a look how this can be done on i.MX6 based systems, like for example the Sabre SD and BD-SL-i.MX6 boards.

The wayland platform plugin provided by the Qt Wayland module is now an official part of Qt 5.4.0. Whenever the necessary dependencies, like the wayland client libraries and the wayland-scanner utility, are available in the sysroot, the platform plugin will be built together with the rest of Qt. In the toolchains and the ready-to-be-flashed reference images for Sabre Lite and Sabre SD everything is in place already. They contain Wayland and Weston 1.4.0, based on Yocto’s recipes (daisy release).

We will use Weston as our compositor. This provides a desktop-like experience out of the box. Those looking for a more customized experience should look no further than the Qt Compositor libaries of the Qt Wayland module which provide the building blocks for easily creating custom compositors with Qt and QML. These components are still under development so stay tuned for more news regarding them in the future.

WP_20141201_012
Video playback and some other applications running on a Sabre SD board

Now let’s see what it takes to run a compositor and our Qt applications on top of it on an actual device. It is important to note that there is no tooling support for such a setup at the moment. This means that deploying and debugging from Qt Creator will likely not function as expected. Some functionality, like touch input and the Qt Virtual Keyboard, will function in a limited manner. For example, the virtual keyboard will appear on a per-application, per-window basis instead of being global to the entire screen. Support for such features will be improved in future releases. For the time being performance and stability may also not be on par with the standard single-process offering. On the positive side, advanced features like accelerated video playback and Qt WebEngine are already functional.

  • Qt Enterprise Embedded’s reference images will launch a Qt application upon boot. This is either /usr/bin/qtlauncher, containing various demos, or the user’s custom application deployed previously via Qt Creator. The launch and lifetime of these applications is managed by the appcontroller utility. To kill the currently running application, log in to the device via adb (adb shell) or ssh (ssh root@device_ip) and run appcontroller –stop.
  • Now we can launch a compositor. For now this will be Weston. The environment variable XDG_RUNTIME_DIR may not be set so we need to take care of that first: export XDG_RUNTIME_DIR=/var/run followed by weston –tty=1 –use-gal2d=1 &. The –use-gal2d=1 option makes Weston perform compositing via Vivante’s hardware compositing APIs and the GC320 composition core instead of drawing textured quads via OpenGL ES.
  • Once the “desktop” has appeared, we are ready to launch clients. The default Qt platform plugin is eglfs, this has to be changed either via the QT_QPA_PLATFORM environment variable or by passing -platform wayland to the applications. The former is better in our case because we can then continue to use appcontroller to launch our apps. Let’s run export QT_QPA_PLATFORM=wayland followed by appcontroller –launch qtlauncher. The –launch option disables some of the tooling support and will make sure a subsequent application launch via appcontroller will not terminate the previous application, as is the case with the default, eglfs-based, single GUI process system.
  • At this point a decorated window should appear on the screen, with the familiar demo application running inside. If the window frame and the title bar are not necessary, performance can be improved greatly by disabling such decorations altogether: just do export QT_WAYLAND_DISABLE_WINDOWDECORATION=1 before launching the application. Note that the window position can still be changed by connecting a keyboard and mouse, and dragging with the Windows/Command key held down.

To summarize:

appcontroller --stop
export XDG_RUNTIME_DIR=/var/run
weston --tty=1 --use-gal2d=1 &
export QT_QPA_PLATFORM=wayland
appcontroller --launch qtlauncher

and that’s it, we have successfully converted our device from a single GUI app per screen model to a desktop-like, multi-process environment. To see it all in action, check out the following video:

Notes From a UX Pro Over a Cup of Joe: UX and Coffee

Welcome back for a chat about user experience (UX) in the real world. Today, I want to talk about user experience and coffee. Now, I know not everyone drinks coffee, so for the sake of discussion, let’s assume that you want to drink some coffee.

Initial Decision

Qt Weekly #22: How to help Qt Support help you more efficiently


If you have used Qt Support before then you may have had to deal with a bit of back and forth with Support trying to get to the heart of the problem that you are having. Therefore in order to try and speed up that process along in the future we have the following tips for you to help you ensure we get all the information that might be useful to us right away.

Installation issues:
– First check that you have all the dependencies for building Qt as indicated here:

http://qt-project.org/doc/qt-4.8/requirements.html

http://qt-project.org/doc/qt-5/build-sources.html
– If the problem occurs when building Qt from source, then send the entire output from configure as well as the output from the make command so we can see everything that has happeend in the run up to the build issue
– If installing from one of the binary installers then re-run the installer with the –verbose option and send the log file it generates

General qmake issues:
– If the makefile/vcxproj/xcodeproj file is not being created correctly then re-run qmake with the extra options “-d -d -d -d 2>debug.txt” and send the debug.txt file it generates. This contains all the debug information from qmake which may be useful.

License not found or is incorrectly invalid issues:
– Delete the .qt-license file from:

*nix/Mac: $(HOME)/.qt-license
Windows: %USERPROFILE%/.qt-license

and delete the following extra file/registry entry:

*nix: $HOME/.config/Digia/LicenseManager.conf
Mac: $HOME/Library/Preferences/com.digia.LicenseManager.plist
Windows: HKEY_CURRENT_USER\Software\Digia\LicenseManager in the registry

Problems with the application starting up:
– If the application itself fails to start then check that the dependencies are found:

*nix: ldd ./executable
Mac: otool -L ./executable.app/Contents/MacOS/executable
Windows: depends executable.exe

On Windows if you do not have depends already you can get this from www.dependencywalker.com. Send the output to us if problems still occur (in the case of Windows you can save it as a dwi file and send that).

If it is a plugin that is failing to start then run the tool from the same location as the executable on the plugin directly instead. For example “ldd ./platforms/libxcb.so”. In addition run the application with the environment variable:

QT_DEBUG_PLUGINS=1

set and send the output that you get from running the application. On Windows you might need to use DebugView in order to see the output if you don’t have a console window or are not running through a debugger.

If the application is crashing:
– Send the stack trace you get when it crashes (in debug mode) and give us the details surrounding what was happening at the time of the crash. Additionally if an example can be produced to reproduce the problem then this certainly goes a long way.

If you have found a bug:
– Sometimes we need to pass on the example that is created to reproduce the bug by a customer into a public bug report system. Please indicate in that case if it is ok to use the example in a public bug report or not so we can save time having to ask first.

Problems related to the network module:
– If at all possible apply the patches from here:
Qt 4:

--- a/src/network/kernel/qhostinfo_win.cpp
+++ b/src/network/kernel/qhostinfo_win.cpp
@@ -134,8 +134,8 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
     QHostInfo results;

 #if defined(QHOSTINFO_DEBUG)
-    qDebug("QHostInfoAgent::fromName(%p): looking up \"%s\" (IPv6 support is %s)",
-           this, hostName.toLatin1().constData(),
+    qDebug("QHostInfoAgent::fromName(): looking up \"%s\" (IPv6 support is %s)",
+           hostName.toLatin1().constData(),
            (local_getaddrinfo && local_freeaddrinfo) ? "enabled" : "disabled");
 #endif

@@ -248,8 +248,8 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)

 #if defined(QHOSTINFO_DEBUG)
     if (results.error() != QHostInfo::NoError) {
-        qDebug("QHostInfoAgent::run(%p): error (%s)",
-               this, results.errorString().toLatin1().constData());
+        qDebug("QHostInfoAgent::run(): error (%s)",
+               results.errorString().toLatin1().constData());
     } else {
         QString tmp;
         QList addresses = results.addresses();
@@ -257,8 +257,8 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
             if (i != 0) tmp += ", ";
             tmp += addresses.at(i).toString();
         }
-        qDebug("QHostInfoAgent::run(%p): found %i entries: {%s}",
-               this, addresses.count(), tmp.toLatin1().constData());
+        qDebug("QHostInfoAgent::run(): found %i entries: {%s}",
+               addresses.count(), tmp.toLatin1().constData());
     }
 #endif
     return results;

--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -3,13 +3,13 @@
TARGET = QtNetwork
QPRO_PWD = $$PWD
DEFINES += QT_BUILD_NETWORK_LIB QT_NO_USING_NAMESPACE
-#DEFINES += QLOCALSERVER_DEBUG QLOCALSOCKET_DEBUG
-#DEFINES += QNETWORKDISKCACHE_DEBUG
-#DEFINES += QSSLSOCKET_DEBUG
-#DEFINES += QHOSTINFO_DEBUG
-#DEFINES += QABSTRACTSOCKET_DEBUG QNATIVESOCKETENGINE_DEBUG
-#DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG
-#DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG
+DEFINES += QLOCALSERVER_DEBUG QLOCALSOCKET_DEBUG
+DEFINES += QNETWORKDISKCACHE_DEBUG
+DEFINES += QSSLSOCKET_DEBUG
+DEFINES += QHOSTINFO_DEBUG
+DEFINES += QABSTRACTSOCKET_DEBUG QNATIVESOCKETENGINE_DEBUG
+DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG
+DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG
QT = core
win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000

Qt 5:

--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -2,13 +2,13 @@ TARGET = QtNetwork
QT = core-private

DEFINES += QT_NO_USING_NAMESPACE
-#DEFINES += QLOCALSERVER_DEBUG QLOCALSOCKET_DEBUG
-#DEFINES += QNETWORKDISKCACHE_DEBUG
-#DEFINES += QSSLSOCKET_DEBUG
-#DEFINES += QHOSTINFO_DEBUG
-#DEFINES += QABSTRACTSOCKET_DEBUG QNATIVESOCKETENGINE_DEBUG
-#DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG
-#DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG
+DEFINES += QLOCALSERVER_DEBUG QLOCALSOCKET_DEBUG
+DEFINES += QNETWORKDISKCACHE_DEBUG
+DEFINES += QSSLSOCKET_DEBUG
+DEFINES += QHOSTINFO_DEBUG
+DEFINES += QABSTRACTSOCKET_DEBUG QNATIVESOCKETENGINE_DEBUG
+DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG
+DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG
win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000

MODULE_PLUGIN_TYPES = \

and then build the network module again and rerun the application. Send us the output that it generates as this will give us a lot of network debug information to look at in case it is useful.

Problems with debugging inside Qt Creator:
– Please include with your support request the contents of the Windows | Views | Debugger Log as this shows all the debugger commands and information.

General tips:
– If you experience a strange crash in your application and you have subclassed Q[Core|Gui]Application then just double check that the constructor’s signature is correct, it should be taking an “int &” and not just an “int” as this can cause problems further down the line although it will compile fine without a warning.

FSFE needs your support for 2015!

“Use, study, share, improve” – these four freedoms are the definition of Free Software for contributors all around the world. The focus of their communities is to produce content and code that can be shared freely, and to have fun and satisfaction on the way. But there is a whole other, non-technical side to the success of Free Software:

  • These freedoms need protection, as they may conflict with the interests of some states and some businesses.
  • These freedoms need explaining, as the benefits they contribute to society and their relation to basic liberties are not always obvious and easy to understand.
  • And these freedoms need organizing, to give the various Free Software communities and contributors one voice where they are usually not heard – for example in capitals, in Brussels, in trade associations, or in research.

The Free Software Foundation Europe does all that, transparently and consistently, so that we don’t have to do it and can concentrate on creating great things. For that, FSFE deserves our support. FSFE is independent and financed by people like you, mostly through donations.

FSFE Logo

For 2015, FSFE is fundraising to secure the budget that finances it’s work:

Free Software Foundation Europe is a pan-European charity, established in 2001 to empower users to control technology. To enable the organisation to intensify its work with the European Commission and to let more people know about Free Software, the FSFE needs another 190,000 Euro for its work in 2015. Next year, the FSFE will push harder than ever to weave software freedom into the fabric of our society.

Donate!

There are multiple ways to take part in this and become a supporter, for example you could sign up as a fellow (like I did). Or your company could become a sponsor. There is also the option for a single, one-off donation. Every small donation helps:

To continue its work in 2015, the FSFE will need 420,000 Euro in total. The organisation has already secured 230,000 Euro thanks to existing sustaining members, regular donations, and merchandise sales. The FSFE requires another 190,000 Euro to underwrite its work in 2015.

FSFE is the one organization in Europe that have software freedom as it’s main focus. If to create general understanding and support for Free Software and Open Standards in politics, business, law and society at large is important to you, please consider supporting this mission in one of the ways described above.


Filed under: Coding, CreativeDestruction, English, FLOSS, KDE, OSS, Qt

Native Android style in Qt 5.4


Qt Quick Controls - Gallery example on Android 4.4

Qt Quick Controls – Gallery example on Android 4.4

As you might have heard, the upcoming Qt 5.4 release delivers a new Android style. This blog post explains what it means in practice for different types of Qt applications.

Qt Widgets

Earlier it has been possible to get native looks for Qt Widgets applications on Android with the help of Ministro, a system wide Qt libraries installer/provider for Android. In Qt 5.4, selected parts of Ministro source code have been incorporated into the Android platform plugin of Qt. This makes it possible for Qt applications to look native without Ministro, even though applications wishing to use services provided by Ministro will continue to do so. In other words, Qt Widgets applications will look native regardless of the deployment method; system wide or bundled Qt libraries.

Qt Quick Controls

The big news is that Qt 5.4 ships a brand new Android style for Qt Quick Controls. A glimpse of the style in action can be seen in the attached screenshot of the Gallery example taken on a Nexus 5 running Android KitKat 4.4. By the way, the Android style requires Android 3.0 (API level 11) or later. On older devices, a generic QML-based fallback style is used instead.

Android 5.0

Android 5.0 preview

DISCLAIMER: work in progress

Mobile platforms keep moving at a fast pace. While we were working hard to deliver a generic native style that works on any Android version 3.0 or later, a new major version of Android was released. Android 5.0 aka Lollipop introduces a new Material design. It comes with so many changes to the underlying platform style, that we haven’t had enough time to catch up with all of those.

Unfortunately, the Material theme support is not yet on an acceptable level. Qt 5.4.0 applications will therefore default to the Holo theme on Android 5.0. The most notable issues are broken disabled states and some missing tint colors, ripple effects and busy/indeterminate animations (QTBUG-42520 and QTBUG-42644).

For the curious ones who cannot wait until the remaining issues have been tackled, it is possible to set the Material theme in AndroidManifest.xml:

<manifest ...>
  <application ... android:theme="@android:style/Theme.Material.Light">
    ...
  </application>
  ...
</manifest>

The same method can be used for setting the light or dark Holo theme for an application, for example. The values are “Theme.Holo.Light” and “Theme.Holo”, respectively.

Contributing to Qt? Come to Oslo in June 2015!


QtCS_2015It’s half a year since the 2014 Qt Contributors’ Summit, and now is a good time to give an early warning about next years QtCS.

We’ll be inviting you to Oslo in early June to come and discuss the current state and future of Qt.

The Qt Contributors’ Summit is an annual event where the people contributing to Qt gather to have fun, discuss where Qt is going and even code a little.

The plans include a pre-party / hack event before the actual summit at The Qt Company offices, two days of unconference style workshops and an evening out in Oslo.

Oslo is a beautiful city in June well worth a visit, especially when combined with the possibility to meet other Qt contributors.

If you aren’t an active contributor yet, don’t worry, you still have plenty of time to start contributing to Qt. Code, documentation, tests, forum activity, helping new users… everything you do to help out Qt is considered contributing.

QtCS 2014 in Berlin was a great event, let’s make QtCS 2015 even better.
The trolls welcome you to the home of Qt!

Qt 4.8.x Support to be Extended for Another Year


Standard Qt support for Enterprise licensees is for 2 years after the next minor or major Qt release is available. For Qt 4.8 it would mean support ending in December 2014, but we will extend it for a whole year to allow seamless migration to Qt 5.

Originally the support for Qt 4.8.x would have ended on 19th December 2014, 2 years after Qt 5.0.0 was released. We are now extending the standard support for 1 more year, meaning that it will not reach end of life until 19th December 2015. By 19th December 2015, Qt 4.8 will have been supported for four years.  Subsequently we now plan to have a Qt 4.8.7 release in Q1 2015. This is planned to be the last release of Qt 4.8.x series, unless there is a need to provide  an update due to a critical security issue.

So what does this mean for you? Well, if you are entitled to support then it means you can still use Qt 4.8.x safe in the knowledge that you will get the same level of support as before until the 19th December 2015. For older versions,we do have an extended lifetime option which you can find more information about by contacting The Qt Company.

We recommend that applications are ported to Qt 5.x as there are new versions of operating systems and compilers coming out which we can’t guarantee will be supported 100% by Qt 4.8. Qt 5 is a solid platform to migrate to with already version Qt 5.4 coming out soon. Therefore, now is the time to start seriously considering to port any existing applications if you haven’t already started doing so. Porting to Qt 5 is pretty straightforward and the documentation at http://qt-project.org/doc/qt-5/portingguide.html will help with that. If you need help, we and our service partners have services available for porting too – more information can be found at http://www.qt.io/services/.

Qt 5.4 Release Candidate Available


I am happy to announce that Qt 5.4 Release Candidate is now available.

After the Qt5.4 Beta release we have done some build & packaging related updates in addition to large number of error fixes based on feedback from Beta release

  • Mac OS X 10.10 is now used in packaging side
  • Android SDK is updated to 21.02
  • MinGW 4.9.1 is taken in the use
  • ICU is updated to 53-1
  • QtWebEngine is separated as its own installable binary package in the installers component tree

Starting from Qt 5.4 RC, Qt for iOS will be build as a fat binary supporting both 32- and 64-bit builds, fulfilling Apple’s requirement for new apps (see https://developer.apple.com/news/?id=10202014a). It also contains improved support for iPhone6/6+.

Qt 5.4 RC packages also contains Qt Creator 3.3 RC and in commercial packages candidates for new commercial value-add items as well.

Please take a tour & try Qt 5.4 Release candidate! It is quite close to final release so please give your feedback:

Please familiarize yourself to Qt 5.4 known issues wiki. For those who have not yet checked what Qt 5.4 brings, please refer to the Qt 5.4 Beta blog post, the wiki article listing new Qt 5.4 features, or the documentation snapshot for more details.

Qt 5.4 Release Candidate is available via online and offline installers. Installers are available from the Qt Account for commercial users of Qt. Open source users can download installers from qt.io downloads page. Qt 5.4 RC can be updated to existing online installation using the Maintenance Tool and selecting package manager.

Qt Creator 3.3 RC released


We are happy to announce the release of Qt Creator 3.3 RC1. Please have a look at the beta release blog post or the change log, for an overview of the new features and key improvements that are waiting for you in this new minor version.

This is the point where we think that we are almost ready to release 3.3.0, so it is a great time for you to download and try the RC, and give us last minute feedback through our bug tracker, the mailing list, or on IRC (#qt-creator on irc.freenode.net).

You find the opensource version on the Qt Project download page, and Enterprise packages on the Qt Account Portal.

Qt Weekly #21: Dynamic OpenGL implementation loading in Qt 5.4


In Qt 5.4 there is a new configure option on Windows: -opengl dynamic. This, in addition to -opengl desktop and -opengl es2, changes the OpenGL implementation (and implicitly the window system interface API) that Qt is built against. However, unlike the previously existing flags, dynamic is something different. Enabling it ensures that neither the Qt libraries nor the applications link directly to an OpenGL implementation, meaning that neither opengl32.lib nor libEGL.lib + libGLESv2.lib are passed to the linker. Instead, Qt will, upon application startup, choose the implementation to load.

Starting with the Qt 5.4 release candidate the previously ANGLE-only pre-built packages are changed to be dynamic builds. It is therefore time to take a closer look at this feature.

Up until Qt 5.4 the binary packages of Qt have been offered in two variants: desktop OpenGL (meaning opengl32.dll) and ANGLE. ANGLE provides an EGL and OpenGL ES 2.0 (soon 3.0) implementation by translating calls and shaders to Direct3D9 or 11. This is very handy for systems that have a lacking OpenGL implementation, for example due to not having the necessary graphics drivers or installed or due to using remote desktop. In addition, Direct3D 11 supports WARP, a software rasterizer.

The ability to work on a wider range of systems made ANGLE a promising prospect for providing OpenGL support for Qt and Qt Quick 2 on Windows, and so it became the default configuration setting. This is true in 5.4 too: configure defaults to ANGLE when no -opengl setting is specified.

However, the results were not always pretty. Offering multiple versions of the binaries causes confusion when getting started (which package to download?) and when deploying (which Qt libraries to ship with my application?). Relying exclusively on ANGLE is not an option in practice. Many desktop applications want OpenGL 3.x and 4.x features. On systems where a proper graphics driver is known to be available, the translation to Direct3D is unnecessary. Advanced modes of operation, like rendering from multiple threads have issues with ANGLE. Therefore the “desktop” OpenGL packages, meaning binaries linked against opengl32, had to be made available.

To eliminate the confusion, Qt 5.4 introduces the concept of dynamic OpenGL implementation selection. The binaries built in this mode are capable of operating with opengl32 (using WGL as the windowing system interface and regular OpenGL), ANGLE (using EGL and Open GL ES) or with a custom opengl32 variant (for example Mesa llvmpipe). As expected, Qt will perform some additional steps during application startup to decide which library to load. After that, all OpenGL calls (for example from Qt Quick) will be routed to this library, via QOpenGLFunctions.

The selection algorithm in Qt 5.4 is simple:

  1. Try opengl32 and check if OpenGL 2.0 functions are available.
  2. If this fails, try ANGLE.
  3. If initialization fails either due to missing ANGLE libraries or some other reason, try opengl32sw.dll. In practice this will be a software rasterizer based implementation. To make it easy to get started, a pre-built version of Mesa llvmpipe is bundled with the binary packages of Qt 5.4.

Pro tip: The debug output printed from the platform plugin can be very helpful to check which implementation gets loaded. To enable these prints, set the environment variable QT_LOGGING_RULES to qt.qpa.gl=true.

Why is this logic useful? Consider the following use cases:

  • When running on a modern system with the necessary graphics drivers installed, the first step will succeed so OpenGL is used normally.
  • When running the same application over remote desktop, the first step will fail and the fallback to ANGLE will be used instead. This functions better with remoting, so the application runs, just like locally.
  • Similarly, on a locked-down Windows 7 PC with no vendor-provided drivers installed, opengl32 will often turn out to be useless, providing only OpenGL 1.x. Direct3D and thus ANGLE may still be functional however.
  • In a virtual machine with limited or no accelerated graphics capabilities both step 1 & 2 may fail. In this case a build of Mesa llvmpipe can be utilized automatically, transparently to the application.

Applications that require desktop OpenGL and are not functional with OpenGL ES can use the QT_OPENGL environment variable or the Qt::AA_UseDesktopOpenGL application attribute before instantiating Q(Gui)Application. ANGLE can also be forced, if needed. For example, when playing video with Qt Multimedia, the best, accelerated path relies on Direct3D – ANGLE interop. Using a non-ANGLE implementation will still work, but possibly with reduced performance. Finally, in some scenarios (e.g. when targetting Windows XP) the robust solution is to deploy a software rasterizer (i.e. opengl32sw.dll) and force that with Qt::AA_UseSoftwareOpenGL in order to ensure a uniform experience across all the target systems. For the relevant settings, see the Windows-specific pages in the Qt documentation.

So how do you take this into use? It is easy: with Qt 5.4 the binary packages that previously were using ANGLE are now built with -opengl dynamic instead. This means that the “suffixless” packages that do not have opengl in the name (for instance, qt-enterprise-windows-x86-msvc2013_64-5.4.0.exe) are now capable of operating both with regular, desktop OpenGL, ANGLE and the software fallbacks, if needed. For the time being the “opengl” packages (built with -opengl desktop) are still being offered. However, these may disappear in Qt 5.5.

There is an important consequence of not linking directly to the OpenGL implementation: no OpenGL functions like glClear() are callable directly anymore. Applications that want to be dynamically switchable must always use QOpenGLFunctions and be prepared to function both on OpenGL and OpenGL ES 2.0. For Qt itself, this is not a problem. All the standard Qt modules, including Qt Quick 2 (qtdeclarative), have been updated to make sure they function as expected in all configurations. For examples, see the documentation and our earlier post about QOpenGLWidget.

Note that this dynamic mode of operation and in particular the software rasterizer fallback are targeted towards general GUI applications based on Qt Quick 2. Applications with heavy OpenGL graphics, for example visualization or games, are obviously not in scope here. Such applications are expected to continue to rely exclusively on modern OpenGL and dedicated graphics hardware. They should enforce a given implementation via QT_OPENGL or the application attributes, so they can continue to use direct OpenGL function calls and other features, like the versioned OpenGL function wrappers. Just add LIBS += -lopengl32 to the application’s .pro file. The migration of an application that today uses and requires the desktop OpenGL builds of Qt is as simple as adding a line to its main() function and a line to the .pro project file. This is naturally not always an option, and this is the reason why Qt 5.4 continues to offer some of the desktop OpenGL packages. The future however lies in the dynamic builds, so applications are expected to gradually migrate to it.

Reminder: Desktops DevRoom @ FOSDEM 2015

We are less than 10 days away from the deadline for the Desktops DevRoom at FOSDEM 2015, the largest Free and Open Source event in Europe.

Do you think you can fill a room with 200+ people out of 6,000+ geeks? Prove it!

Check the Call for Talks for details on how to submit your talk proposal about anything related to the desktop:

  • Development
  • Deployment
  • Community
  • SCM
  • Software distribution / package managers
  • Why a particular default desktop on a prominent Linux distribution ;-)
  • etc

http://www.elpauer.org/2014/10/fosdem-2015-desktops-devroom-call-for-talks/

Raspberry Pi Update

Since my last blog about the Raspberry Pi in August, there have been a number of interesting new developments and the Raspberry Pi project has continued to move ahead.

Qt Downloads moving to qt.io


QtProject_02-Download_Page_768x400As you have noticed from the banner on the qt-project.org download page, downloads are moving to qt.io. This is part of unifying Qt and defragmenting the community. The intention is to gradually move to using one Qt website for all services.

Downloads have been available on the unified Qt site for some time now, and everything has been working well there, so today we will start forwarding all traffic that is coming to qt-project.org/downloads to the qt.io/download page.

On the unified Qt download page you’ll find all the downloads as before plus the commercial options on one page.

Next steps

Next in the site unification is the moving of the Qt blog and documentation to the new site and making a unified login service for all the Qt online services.

The Qt blog will be moving to the qt.io domain with a new layout in the coming weeks. This change will be straightforward and isn’t expected to cause any issues.

We received good feedback from you on the new look and feel of the documentation. Thank you. We made changes based on the feedback, and now the Qt 5.4.0 release documentation will be available on doc.qt.io. You can already see the release candidate documentation at doc.qt.io. The rest of the documentation will also be moving to the new address later on.

The new unified login, Qt Account, will enable you to use the same credentials for forums, wiki, bugs and all the other services. We will start moving services that need a login to qt.io as soon as the new login system is properly tested and available for use. The current plan is that in early 2015 we should have most of the developer services in the unified Qt site.

If you have feedback or questions, please leave a comment!

Qt on Android Episode 5

Update: Here you have also the Chinese version, thanks goes to Foruok

After we’ve seen how to set up the development environment, how to use Qt on Android and what deployment systems are available and how to sign the final package, it’s time to move forward. In this article we are going to learn about JNI.

Why do we need JNI?

Because it is impossible for Qt to implement all Android features. To use any of them we’ll need to use JNI to access them. JNI the only way to do calls to/from Java world from/to native (C/C++) world.

JNI intro

In this article we’ll learn the basics of the JNI, in the next article(s) we’re going to learn how to use this knowledge to correctly extend Qt on Android apps.

There is tons and tons of information on this matter on the net, in this article I’m focusing only on how to do JNI on Android using Qt. Starting with 5.2, Qt ships Qt Android Extras module. This module makes our life much more pleasant when we’ll have to do JNI.

There are two use cases:

  • Call a Java function from C/C++
  • Callback a C/C++ function from Java

Call a Java function from C/C++

Calling a Java function from C/C++ using Qt Android Extras module is quite easy.

First let’s create a Java static method:

// java file android/src/com/kdab/training/MyJavaClass.java
package com.kdab.training;

public class MyJavaClass
{
    // this method will be called from C/C++
    public static int fibonacci(int n)
    {
        if (n < 2)
            return n;
        return fibonacci(n-1) + fibonacci(n-2);
    }
}

So, we defined fibonacci static method into MyJavaClass class into com.kdab.training package. This method returns the computed fibonacci number.

Now let’s see how to call it from Qt. The first step is to make sure we are using the android extras, so we need to add it to our .pro file.

# Changes to your .pro file
# ....
QT += androidextras
# ....

Then do the actual call:

// C++ code
#include <QAndroidJniObject>
int fibonacci(int n)
{
    return QAndroidJniObject::callStaticMethod<jint>
                        ("com/kdab/training/MyJavaClass" // class name
                        , "fibonacci" // method name
                        , "(I)I" // signature
                        , n);
}

Yes, that’s all folks!

Let’s take a closer look to this code and see what we have here:

  • we are using QAndroidJniObject::callStaticMethod to call a Java static method.
  • first argument is the fully-qualified class name. The fully-qualified name for a class (or interface) is the package name (com/kdab/training) followed by the class/interface name(MyJavaClass), separated by a slash (/) (NOT by a period, the period is used only in Java world not in C/C++ world!)
  • the next argument is the method name
  • the next is the method signature
  • the next arguments are the arguments that will be passed to the java function

Please check QAndroidJniObject documentation for more information about method signature and the arguments types.

Callback a C/C++ function from Java

In order to callback a C/C++ function from Java you need to do the follow steps:

  • declare the native method(s) in Java, using native keyword
  • register native method(s) in C/C++
  • do the actual call

Declare the native method(s) in Java, using native keyword.

Let’s change the previous java code a little bit:

// java file android/src/com/kdab/training/MyJavaClass.java
package com.kdab.training;

class MyJavaNatives
{
    // declare the native method
    public static native void sendFibonaciResult(int n);
}

public class MyJavaClass
{
    // this method will be called from C/C++
    public static int fibonacci(int n)
    {
        if (n < 2)
            return n;
        return fibonacci(n-1) + fibonacci(n-2);
    }

    // the second method that will be called from C/C++
    public static void compute_fibonacci(int n)
    {
        // callback the native method with the computed result.
        MyJavaNatives.sendFibonaciResult(fibonacci(n));
    }
}

Let’s take a closer look to this code and see what we have here:

  • personally, I prefer to keep all my native method(s) in a separate class, so, I declared sendFibonaciResult native method into MyJavaNatives class into com.kdab.taining package. This native method will be used by compute_fibonacci static method to callback the C/C++ world to send the computed result instead to return it as fibonacci method does.
  • compute_fibonacci, this method will be called from C/C++, but instead to return the result as fibonacci method does, it uses sendFibonaciResult native method to callback the C/C++ world to end the result.

If you try only this code it will fail, because sendFibonaciResult is not registered, and Java VM doesn’t know it yet.

C/C++ register native methods

Now let’s see how to register the function in C/C++.

First thing you need to know is that you can register only function(s). You can NOT register C++ class (non-static) members!

There are two ways to register native methods, we are going to check both ot them:

Registering functions using Java_Fully_Qualified_ClassName_MethodName

#include <jni.h>
#include <QDebug>

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL
  Java_com_kdab_training_MyJavaNatives_sendFibonaciResult(JNIEnv *env,
                                                    jobject obj,
                                                    jint n)
{
    qDebug() << "Computed fibonacci is:" << n;
}

#ifdef __cplusplus
}
#endif

Let’s take a closer look to this code and see what we have here:

  • First thing we’ve seen, is that all the functions must be exported as C functions and NOT as C++ functions!
  • The function name MUST follow the next template: Java word, followed by the package name, then followed by the class name, then followed by the method name,separated by an underscore (_)
  • When JavaVM loads the .so file, it will search for this template and it will automatically register all your functions for you
  • the first argument (env) of the function is a pointer to JNIEnv object.
  • the second argument (obj) is a reference to the Java object inside which this native method has been declared.
  • the first and second arguments are mandatory for every function that you’ll register.
  • the next arguments must match the java native method arguments. So, our third argument is actually our first (and only) java native method argument. This is the argument that compute_fibonacci will pass to sendFibonaciResult native method when it calls it.

Using this method to register is quite easy to declare and register, but it has a few disadvantages:

  • the function names are huge:

    Java_com_kdab_training_MyJavaNatives_sendFibonaciResult

  • the library must to export all functions
  • unsafer, there is no way for the JavaVM to check the function signature, because the functions are exported as C functions and NOT as C++ functions!

Use JNIEnv::RegisterNatives to register native functions

In order to use JNIEnv::RegisterNatives to register native functions, we need to do the following 4 steps to use it:

  • step 1: we need get access to an JNIEnv pointer. The easiest way is to define and and export JNI_OnLoad function, (once per .so file) in any .cpp file we like.
  • step 2: create a vector with all C/C++ methods that we want to register.
  • step 3: find the ID of java class that declares these methods using JniEnv::FindClass
  • step 4: call JNIEnv::RegisterNatives(java_class_ID, methods_vector, n_methods)
// C++ code
#include <jni.h>
#include <QDebug>

// define our native method
static void fibonaciResult(JNIEnv */*env*/, jobject /*obj*/, jint n)
{
    qDebug() << "Computed fibonacci is:" << n;
}

// step 2
// create a vector with all our JNINativeMethod(s)
static JNINativeMethod methods[] = {
    { "sendFibonaciResult", // const char* function name;
        "(I)V", // const char* function signature
        (void *)fibonaciResult // function pointer 
    }
};

// step 1
// this method is called automatically by Java VM
// after the .so file is loaded
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
{
    JNIEnv* env;
    // get the JNIEnv pointer.
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6)
           != JNI_OK) {
        return JNI_ERR;
    }

    // step 3
    // search for Java class which declares the native methods
    jclass javaClass = env->FindClass("com/kdab/training/MyJavaNatives");
    if (!javaClass)
        return JNI_ERR;

    // step 4
    // register our native methods
    if (env->RegisterNatives(javaClass, methods,
                            sizeof(methods) / sizeof(methods[0])) < 0) {
        return JNI_ERR;
    }
    return JNI_VERSION_1_6;
}

Let’s check the code for a better understanding:

  • static void fibonaciResult(JNIEnv */*env*/, jobject /*obj*/, jint n) it is the method that we’re registering and which Java VM will call.
  • the first argument (env) of the function is a pointer to JNIEnv object.
  • the second argument (obj) is a reference to the Java object inside which this native method has been declared.
  • the first and second arguments are mandatory for every function that you’ll register.
  • the next arguments must match the java native method arguments. So, our third argument is actually our first (and only) java native method argument. This is the argument that compute_fibonacci will pass to sendFibonaciResult native method when it calls it.
  • we add the method to a vector (methods) of JNINativeMethod structures.
  • JNINativeMethod structure has the following fields:
    • const char* name – it is the function name, it has to be exactly as the native function name that we’ve declared in Java
    • const char* signature – it is the function signature, it has to match the native function arguments that we’ve declared in Java
    • void* fnPtr – it is the C/C++ function pointer. In our case it’s a pointer to static void fibonaciResult(JNIEnv */*env*/, jobject /*obj*/, jint n) function. As you can see the C/C++ function name doesn’t matter, the Java VM needs only a pointer to it.
  • the rest of the code is clear and easy and I don’t think it needs any explanations than the comments.

Even if it looks a little bit complicated to use it, this method has the following advantages:

  • the C/C++ function can have any name you want
  • the library needs to export only one function (JNI_OnLoad)
  • safer, because the Java VM checks the declared signature

It’s just a matter of taste which method you decide to use to register your native functions. I do recommend you to use JNIEnv::RegisterNatives as it offers you extra protection because the Java VM checks the functions signature and it throws an exception if it doesn’t match.

Conclusion

In this article we’ve learned the basics of the JNI, in the next article(s) we’re going to learn how to use this knowledge to correctly extend Qt on Android apps. We’ll talk more about Qt on Android apps architecture, how to extend the Java part of your application and we’ll take a real life example to show how to correctly do safe calls from Qt thread to Android UI thread and vice-versa.

Thank you for your time!

The post Qt on Android Episode 5 appeared first on KDAB.

User Experience Design Principles of a Natural User Interface (NUI)

In a previous blog post (Defining a Natural User Interface) I explained how finding a clear and concise definition of a Natural User Interface (NUI) was not easy. Finding a clear and concise list of user experience design principles for a NUI is even more challenging. An obvious reason for this is that NUIs encompass a broad range of possibilities, and it’s difficult to be general enough to cover the range and at the same time specific enough to be useful.

QML wrappers for native Android components

TL;DR It might be simpler than you think to wrap native UIs with the QtQml module, but it does require a good understanding of the underlying platform

In my previous post, I showed how you can work with platform-native classes and use the QtAndroidExtras module to create UIs from code. One of the downsides was the extra code complexity you had to manage. The "Qt way" of doing UIs is, however, by using QML, for the reasons of brevity, development speed and flexibility. I cobbled together a custom Android component module to demonstrate this (sources available on GitHub) - the 40+ thick line C++ UI example suddenly becomes a lot more readable and fun to work with.



Qt does have a solution for native-looking UIs on Android in the form of QtQuick.Controls, so my reasoning here is more to show

  • what are the advantages of custom components
  • how custom components are done
  • what are the pitfalls of custom component sets
What are the advantages? If there is no native-looking component set, it's quite clear - you simply have no alternative. If QtQuick.Controls does exist for your platform (see the case of Android), there is still a number of reasons why you might consider going custom. First, you get the full functionality and availability of the platform-native set. QtQuick.Controls gives you something that is closer to a lowest common denominator, with a lot of platform-specific components/functionality missing and occasionally some input method quirks. By skipping this, you create UIs which are not just "close-to-platform-native", but effectively *are* platform native. Second, you get the full performance. By having a wrapper, there will still be a slight penalty for loading Qt, and parsing/constructing the QML objects, but there is no compromise once the UI is instantiated. I personally also like that you can use the platform-native documentation and examples, since you're just using QML syntax, but class names, properties and general usage pattern remain the same as on the platform.

How does one go about creating a new component set? As you've seen from the first QML snippet, all we really need is the QtQml module. If you start creating with a completely custom *native* component set (ie not deriving from an existing QtQuick or QtQuick.Controls base) you get a really basic set of components to work with, namely Component, QtObject, Binding, Connections, Timer. All you native components will be actually QObject derived C++ objects, registered with the QML system, as described here. The classes themselves are still plain Qt classes, here's how my activity.h looks like:



After that, you need to register every such object with the QML engine (usually in your main.cpp) :

qmlRegisterType("OutQross.Android", 0, 1, "Activity");

With this we can start instantiating our custom objects from QML. The QtObject class/element unfortunately does not have a lot of the functionality normally coming from Item (including having a default children property), so I created an OutQrossItem helper class for this purpose, which is the base class for all my Qml elements.



Finally, let's see the gritty innards of a custom component class, an Android Button in this case



As you can see, I still use the same UI inflate paradigm as Android to actually instantiate the button (this way we also avoid the question of the order of object initialization or property settings), and you can also see how a property can we wrapped. This means that the full power of QML - bindings, signals/slots and JS are available to us as the properties are mapped to the native components. This is crucial if you are building your own component sets, as otherwise you're just making a syntax converter - and this is also the answer to how this is different to just converting QML to Android .XML UIs or vice versa.

For completeness' sake, let's mention that the .APK was 6.9MB and the memory usage of the HelloWorld app was 61510kb (about halfway between the version in my previous blog post and the "full" QtQuick experience)

There are some pitfalls as well. First, while not rocket science, it's actual work. If you have an extensive GUI widget set or library (like Android), you probably want to use or write some sort of wrapper code generator as manually creating and maintaining a full wrapper set can be daunting. Second, there might be specific UI caveats - for example, in the case of my Android example, to keep it simple, I'm not actually running on the UI thread. This means that in my particular implementation while native component and property updates happen via the bindings, they might not immediately appear on the screen. This can be resolved, but it does require a very good understanding of how the native platform works. My advice is that you shouldn't consider writing wrappers because you don't know how the platform-native UIs work - it should primarily be done to accelerate future development and prototyping.

Injeqt 0.9.0 released

First official (beta!) version of Injeqt dependency injection library for Qt was released today. I can be downloaded from GitHub releases page.

For last 3 weeks I was working on Kadu and switching some parts of it to use Injeqt for its objects and services wiring. As it turns out, it all works very well already. There is no need to postpone Injeqt release until it gains additional features (and I have big plans for it).

0.9.x series will continue until Kadu 2.0 release with only bugfixes. I don't expect a lot of them (Injeqt has very nice unit tests coverage), but better safe than sorry. Exported API is very minimal and should not be changed (only extended) in a long time.

If you wish to try it - please do it now. I would be happy to see more use cases and real world applications before committing 100% to 1.0 release.

Enjoy!

Qt Weekly #20: Completing the offering: QOpenGLWindow and QRasterWindow


Together with the introduction of QOpenGLWidget, Qt 5.4 adds two more classes: QOpenGLWindow and QRasterWindow. Let us now look at the list of native window classes and OpenGL container widgets. The list may look long and confusing at first glance, but it is all quite logical so everything will fall into place quickly:

  • QWindow: Represents a native window in the windowing system. The fundamental window class in Qt 5. Every top-level window, be it widget or Quick based, will have a QWindow under the hood. Can also be used directly, without widgets or Quick, both for OpenGL and software rendered graphics. Has no dependencies to the traditional QWidget stack.
  • QRasterWindow: Convenience wrapper over QWindow for software rendered graphics.
  • QOpenGLWindow: Convenience wrapper over QWindow for OpenGL graphics. Optionally backed by a framebuffer object, but the default behavior (and thus performance) is equivalent to QWindow.
  • QOpenGLWidget: The modern replacement for Qt 4’s QGLWidget. A widget for showing OpenGL rendered content. Can be used like any other QWidget. Backed by a framebuffer object.
  • QQuickWindow: A QWindow subclass for displaying a Qt Quick 2 (QML) scene.
  • QQuickView: Convenience wrapper for QQuickWindow for easy setup of scenes loaded from QML files.
  • QQuickWidget: The equivalent of QQuickView in the QWidget world. Like QOpenGLWidget, it allows embedding a Qt Quick 2 scene into a traditional widget-based user interface. Backed by a framebuffer object.

For completeness sake, it is worth noting two additional APIs:

  • QQuickRenderControl: Allows rendering Qt Quick 2 scenes into framebuffer objects, instead of targeting an on-screen QQuickWindow.
  • QWidget::createWindowContainer(): In Qt 5.1 & 5.2 the only way to embed Qt Quick 2 content (or in fact any QWindow) into a widget-based UI was via this function. With the introduction of QQuickWidget and QOpenGLWidget this approach should be avoided as much as possible. Its usage should be restricted to cases where it is absolutely neccessary to have a real native window embedded into the widget-based interface and the framebuffer object-based, more robust alternatives are not acceptable, or where it is known in advance that the user interface layout is such that the embedded window will not cause issues (for example because the embedded window does not care about input, is not part of complex layouts that often get resized, etc.).

We will now take a look at no. 2 & 3, the QWindow convenience wrappers.

Ever since the introduction of the QPA architecture and QWindow, that is, since Qt 5.0, it has been possible to create windows based on QWindow that perform custom OpenGL drawing. Such windows do not use any QWidget-derived widgets, instead they render everything on their own. A game or a graphics intensive application with its own custom user interface is a good example.

This is the most lightweight and efficient way to perform native OpenGL rendering with Qt 5. It is free from the underlying complexities of the traditional widget stack and can operate with nothing but the QtCore and QtGui modules present. On space-constrained embedded devices this can be a big benefit (no need to deploy QtWidgets or any additional modules).

Power and efficiency comes at a cost: A raw QWindow does not hide contexts, surfaces and related settings, and it does not provide any standard mechanism for triggering updates or opening a QPainter (backed by the OpenGL 2.0 paint engine) targeting the window’s associated native window surface.

For example, a simple QWindow subclass that performs continous drawing (synchronized to the display’s vertical refresh by the blocking swapBuffers call) both via QPainter and directly via OpenGL could look like the following:

class MyWindow : public QWindow
{
public:
    MyWindow() : m_paintDevice(0) {
        setSurfaceType(QSurface::OpenGLSurface);

        QSurfaceFormat format;
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        setFormat(format);

        m_context.setFormat(format);
        m_context.create();
    }

    ~MyWindow() { delete m_paintDevice; }

    void exposeEvent(QExposeEvent *) {
        if (isExposed())
            render();
    }

    void resizeEvent(QResizeEvent *) {
        ...
    }

    void render() {
        m_context.makeCurrent(this);

        if (!m_paintDevice)
            m_paintDevice = new QOpenGLPaintDevice;
        if (m_paintDevice->size() != size())
            m_paintDevice->setSize(size());

        QOpenGLFunctions *f = m_context.functions();
        f->glClear(GL_COLOR_BIT | GL_DEPTH_BUFFER_BIT);
        // issue some native OpenGL commands

        QPainter p(m_paintDevice);
        // draw using QPainter
        p.end();

        m_context.swapBuffers(this);

        // animate continuously: schedule an update
        QCoreApplication::postEvent(new QEvent(QEvent::UpdateRequest), this);
    }

    bool event(QEvent *e) {
        if (e->type() == QEvent::UpdateRequest) {
            render();
            return true;
        }
        return QWindow::event(e);
    }

private:
    QOpenGLContext m_context;
    QOpenGLPaintDevice *m_paintDevice;
};

Now compare the above code with the QOpenGLWindow-based equivalent:

class MyWindow : public QOpenGLWindow
{
public:
    MyWindow() {
        QSurfaceFormat format;
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        setFormat(format);
    }

    void resizeGL(int w, int h) {
        ...
    }

    void paintGL() {
        QOpenGLFunctions *f = context()->functions();
        f->glClear(GL_COLOR_BIT | GL_DEPTH_BUFFER_BIT);
        // issue some native OpenGL commands

        QPainter p(this);
        // draw using QPainter

        // animate continuously: schedule an update
        update();
    }
};

That is a bit shorter, isn’t it. The API familiar from QOpenGLWidget (initializeGL/resizeGL/paintGL) is there, together with the update() function and the ability to easily open a painter on the window. While QOpenGLWindow, when used this way, does not remove or add anything compared to raw QWindow-based code, it makes it easier to get started, while leading to shorter, cleaner application code.

QRasterWindow follows the same concept. While everything it does can be achieved with QWindow and QBackingStore, like in the raster window example, it is definitely more convenient. With QRasterWindow, the example in question can be reduced to something like the following:

class RasterWindow : public QRasterWindow
{
    void paintEvent(QPaintEvent *) {
        QPainter painter(this);
        painter.fillRect(0, 0, width(), height(), Qt::white);
        painter->drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, QStringLiteral("QRasterWindow"));
    }
};

Painters opened on a QOpenGLWindow are always backed by the OpenGL paint engine, whereas painters opened on a QRasterWindow are always using the raster paint engine, regardless of having OpenGL support enabled or available at all. This means that QRasterWindow, just like the traditional widgets, is available also in -no-opengl builds or in environments where OpenGL support is missing.

Now, what about incremental rendering? In the QRasterWindow example above there is strictly speaking no need to clear the entire drawing area on each paint. Had the application wished so, it could have continued drawing over the existing, preserved backing store content in each invocation of paintEvent(), as long as the window did not get resized. With QGLWidget, QWindow or the QOpenGLWindow example shown above this is not possible, unless preserved swap is enabled via the underlying windowing system interface, since on each paintGL() call the color buffer contents is effectively undefined. QOpenGLWidget does not have this problem since it is backed by a framebuffer object instead of targeting the window surface directly. The same approach can be applied to QOpenGLWindow too. Hence the introduction of the different update behaviors that can be set on a QOpenGLWindow.

Take the following QWindow-based code:

class MyWindow : public QWindow
{
public:
    MyWindow() : m_paintDevice(0), m_fbo(0), m_iter(0) {
        ... // like in the first snippet above
    }

    ...

    void render() {
        m_context.makeCurrent(this);

        if (!m_fbo || m_fbo->size() != size()) {
            delete m_fbo;
            m_fbo = new QOpenGLFramebufferObject(size(), QOpenGLFramebufferObject::CombinedDepthStencilAttachment);
            m_iter = 0;
        }

        if (!m_paintDevice)
            m_paintDevice = new QOpenGLPaintDevice;
        if (m_paintDevice->size() != size())
            m_paintDevice->setSize(size());

        m_fbo->bind();
        QPainter p(m_paintDevice);

        // Draw incrementally using QPainter.
        if (!m_iter)
            p.fillRect(0, 0, width(), height(), Qt::white);

        p.drawText(QPointF(10, m_iter * 40), QString(QStringLiteral("Hello from repaint no. %1")).arg(m_iter));

        ++m_iter;

        p.end();
        m_fbo->release();

        // Now either blit the framebuffer onto the default one or draw a textured quad.
        ...

        m_context.swapBuffers(this);

        // animate continously: schedule an update
        QCoreApplication::postEvent(new QEvent(QEvent::UpdateRequest), this);
    }

private:
    QOpenGLContext m_context;
    QOpenGLPaintDevice *m_paintDevice;
    QOpenGLFramebufferObject *m_fbo;
    int m_iter;
};

For brevity the code for getting the framebuffer’s content onto the window surface is omitted. With QOpenGLWindow’s PartialUpdateBlit or PartialUpdateBlend the same can be achieved in a much more concise way. Note the parameter passed to the base class constructor.

class MyWindow : public QOpenGLWindow
{
public:
    Window() : QOpenGLWindow(PartialUpdateBlit), m_iter(0) {
        QSurfaceFormat format;
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        setFormat(format);
    }

    void resizeGL(int, int) {
        m_iter = 0;
    }

    void paintGL() {
        QPainter p(this);

        // Draw incrementally using QPainter.
        if (!m_iter)
            p.fillRect(0, 0, width(), height(), Qt::white);

        p.drawText(QPointF(10, m_iter * 40), QString(QStringLiteral("Hello from repaint no. %1")).arg(m_iter));

        ++m_iter;

        update();
    }

private:
    int m_iter;
};

That’s it, and there is no code omitted in this case. Internally the two are approximately equivalent. With the QOpenGLWindow-based approach managing the framebuffer object is no longer the application’s responsibility, it is taken care by Qt. Simple and easy.

Native UI in Qt on Android (without QtQuick.Controls)

TL;DR - Yes, you can do a fast, no-compromise native UI without QtQuick on Android, and you'll use a lot less resources than a full QtQuick app, at the cost of somewhat messy code.

Nowadays Qt for Android comes with a nice QtQuick-compatible set of native-looking Android controls in the form of QtQuick.Controls. This blog post is not about them :) Let's go a bit off the beaten path - can we create a Qt application with a graphical, performant, native UI without using QtQuick (or QWidgets)? What are the advantages and disadvantages to such an approach?

In a blog post Artem Marchenko lists a couple of approaches how a Qt based native-looking UI would be possible, but these all include QML in one form another, which is not quite what we're after in this particular case. Another interesting project is Ben Lau's QAndroidRunner which combines native UIs and QML. Here, however, we'll focus how far can you get without ever touching QML or QtQuick.

The key to using Android classes and resources is the QAndroidExtras module (it's an add-on module that has been around since Qt 5.2). The class I'm heavily relying on is QAndroidJNIObject which allows Java class/object instantiation and manipulation. Thus, the two includes we'll use to enable creating native objects are

#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QtAndroid>

When it comes to Android UIs, the first stop is the Activity - on Android activities are how we interact with the user. This is effectively a window on which we put all our widgets and UI elements. Luckily, starting with Qt 5.3, we have a simple way of retrieving an activity with the QtAndroid::androidActivity function.

QAndroidJniObject activity = QtAndroid::androidActivity();

Let's get to the meat of the matter - we'll need to create native layout and widget objects and set their parameters from Qt. Here's how that looks like

QAndroidJniObject layout("android/widget/RelativeLayout", 
"(Landroid/content/Context;)V",
activity.object());

The first parameter is the Java class name, the second the Java method signature (see here for a few more examples, "javap -s" is your friend), and the third parameter is the actual object used as the parameter (as activity is a QAndroidJniObject, we need to use the object() method). With the call above we create a Layout and assign it to the activity.

We can also call methods of our objects:

button.callMethod<void>("setTextColor", "(I)V", -1); // Color.WHITE

Putting all these together, we can create a basic, but full-fledged Android application:



...resulting in...


This "Hello world" code is clearly quite a bit more complicated than it's QML counterpart:



The complexity downside is quite obvious - it's hard to beat QML's brevity and clarity. Another, perhaps not immediately visible downside is that this particular style of C++ code is more error-prone - there is no type safety as the objects are generated dynamically, so on errors, it's easy to end up with NULL objects and segfaults.

Why would anyone use it, then? Let's take a look at resource consumption:

The APK size for the non-QML Android version of Hello World is 5,663,420 bytes, while the APK with the Controls included is 10,406,706. The difference could be even bigger, though, as the default android mkspec includes a few extra Qt modules. It should be possible to get the minimum APK size down to around 3MB. If you are using Ministro, this might not be as big of an issue, but for self-contained applications, or embedded, this can shave a few precious megabytes off of the application.

It's not just flash storage and network bandwidth we can save though - there is a memory-usage difference as well. While adb dumpsys meminfo is not a perfect way to measure memory usage, it is indicative:

40761 kB: org.qtproject.example.QtJavaHelloWorld
77531 kB: org.qtproject.example.QmlHelloWorld

While a ~35MB of minimum framework tax might not sound like much in the era of devices with several gigabytes of RAM, using a complex QML structure can inflate the difference further. On embedded and legacy devices every megabyte counts, so even this 35MB difference can help (plenty of low-end Android devices with 256-512MB of RAM).

There are other benefits to not using QtQuick controls - controls are a "lowest common denominator" approach designed to easy cross-platform development. It does not contain all UI widgets and elements, nor functionality offered by Android APIs. By using the approach as demonstrated, there is no compromise - the full UI arsenal is at our disposal, at the exact same performance as for regular Java apps.

Finally, the QtQuick controls version depends on the Qt version shipped with the application. In the non-Controls version we always get the native controls, with native styling and behavior, even if the platform release is newer than what our QtQuick.Controls version supports.

To summarize, the advantages to a Controls-less approach are:
  • Native UI performance
  • Smaller APK size (currently at least ~5MB less, potentially ~7MB)
  • Smaller memory footprint (35MB for Hello world, more as app complexity increases)
  • Full UI functionality available, regardless of Qt version
  • Styling always latest platform-native
Disadvantages

  • Not cross-platform
  • Significantly increased code complexity, especially with more complex UIs
  • Harder to debug due to dynamic nature and lack of tooling support

It's actually possible to mitigate some of the disadvantages, so stay tuned for further posts on this topic!

C++14 for Qt programmers

C++14 is the name of the version of the standard to be released this year. While C++11 has brought many more feature that took time to be implemented by the compilers, C++14 is a much lighter change that is already implemented by compilers such as clang or gcc.

Qt 5 already was adapted in many ways so you can make use of the new features of C++11. You can read about that in my previous article. C++11 in Qt5 . This article mention some of the changes in C++14 and the impact on Qt users.

Generic lambda

C++11 introduced lambda function, and Qt5 allow you to connect signals to them with the new connect syntax. C++14 simplify the use of lambda function as the arguments can be automatically deduced. You can use auto as parameter type instead of explicitly writing the type.

 connect(sender, &Sender::valueChanged, [=](const auto &newValue) {
        receiver->updateValue("senderValue", newValue);
    });

Internally, lambda function is just a functor object with an operator(). With generic lamdba, that operator is now a templated function. I had to make a change which was included in Qt 5.1 already to support such functors.

C++14 also adds the possibility to have expressions in the capture.

 connect(sender, &Sender::valueChanged, [reciever=getReciever()](const auto &newValue) {
        receiver->updateValue("senderValue", newValue);
    });

Relaxed Constant expressions

C++11 came with the new constexpr keyword. Qt 4.8 has added a new macro Q_DECL_CONSTEXPR that expands to constexpr when supported, and we have been using it for many function when possible in Qt 5.

C++14 is relaxing the rules of what is allowed in a constexpr. C++11 rules were only allowing a single return statement, and could only be applied on const functions. C++14 allow pretty much any code that can be evaluated at compile time.

/* This function was not valid in C++11 because it is composed of several statements,
 * it has a loop, and a local variable. It is now allowed in C++14 */
constexpr int myFunction(int v) {
  int x = 1;
  while (x < v*v)
    x*=2;
  return x;
}

Member functions declared as constexpr in C++11 were automatically considered as const. It is no longer the case as non-const function can also be constexpr.
The result of this change is that constexpr member functions that were not explicitly marked as const will change const-ness in C++14, and this is a binary incompatible change. Fortunately in Qt, all Q_DECL_CONSTEXPR member functions were also explicitly declared as const to keep binary compatibility with non C++11 code.

So now we can start annotating non-const functions such as operator= of many classes. For this reason, Qt 5.5 will come with a new macro Q_DECL_RELAXED_CONSTEXPR which expands to constexpr when the compiler is in a C++14 mode. We will then be able to start annotating relevant functions with Q_DECL_RELAXED_CONSTEXPR

Small features

C++14 also comes with a lot of small convenience feature. That do not have direct impact on Qt, but can be used in your program if you enable C++14. We just made sure that tools like moc can handle them.

Group Separators in Numbers

If you are writing huge constant in your code, you can now now use ' as a group separator:

    int i = 123'456'789;

Binary literal

In C++ you can write your number in decimal, octal (starting your number with 0), hexadecimal (starting with 0x). You can now also write in binary by using the 0b prefix.

    int i = 0b0001'0000'0001;

Automatic return type detection

If you have an inline function, you can use auto as a return type, and you do no longer need to specify it. The compiler will deduce it for you

// return type auto detected to be 'int'
auto sum(int a, int b) { return a+b; }

This is, however, not supported for slot or invokable method as moc would not be able to detect the return type

Variable template

You could have functions template or class template. Now you can also have variable template.

template<typename T> const T pi = 3.141592653589793;
/*...*/
    float f = pi<float>;
    double d = pi<double>;

Uniform initialization of structures with non static data member initializers

In C++11, you can use the uniform initialization to initialize a struct that has no constructor by initializing all the members. C++11 also added the possibility to have inline non static data member initiazers directly in the class declaration. But you could not use the two at the same time. In C++14, you can. This code works and do what you would expect:

struct MyStruct {
    int x;
    QString str;
    bool flag = false;
    QByteArray str2 = "something";
};

    // ...
    // did not compile in C++11 because MyStruct was not an "aggregate" 
    MyStruct s = { 12, "1234", true };
    Q_ASSERT(s.str2 == "something");

Reference Qualifiers

This is not a C++14 feature, but a C++11 change. But we only started to make use of this late in the Qt5 cycle and I did not mention it in a previous blog post so I'll mention it here.

Consider this code:

    QString lower = QString::fromUtf8(data).toLower();

fromUtf8 returns a temporary. It would be nice if the toLower could re-use the memory allocated by the string and do the transformation in place. Well that's what the reference qualifiers for member functions are for.

(code simplified from qstring.h:)

class QString {
public:
    /* ... */

    QString toLower() const &
    { /* ... returns a copy with lower case character ... */ }
    QString toLower() &&
    { /* ... do the conversion in-place ... */ }
    
    /* ... */
};

Notice the '&' and '&&' at the end of toLower. Those are references qualifier and let overload a function depending on the reference type of the 'this' pointer, just like the const qualifier let overload on the constness of this. When toLower is called on a temporary (a rvalue reference) the second overload (the one with &&) will be chosen and the transformation will be done in place.

The functions that benefit from the optimisation in Qt 5.4 are: QString::toUpper, QString::toLower, QString::toCaseFolded, QString::toLatin1, QString::toLocal8Bit, QString::toUtf8, QByteArray::toUpper, QByteArray::toLower, QImage::convertToFormat, QImage::mirorred, QImage::rgbSwapped, QVersionNumber::normalized, QVersionNumber::segment

Changes in the standard library.

C++11 and C++14 have added a lot of feature to the standard library, competing with many of the features of QtCore. However, Qt makes little use of the standard library. In particular, we do not want to have the standard library as part of the ABI. This would allow to stay binary compatible even when the standard library is changed (example libstdc++ vs. libcpp). Also, Qt still supports older platforms that do not have the C++11 standard library. This really limits our uses.

Yet, Qt5 deprecated its own algorithms library and is now recommending to use the algorithms from the STL (example, std::sort instead of qSort).

Conclusion

It may still take some time before you can use those features in your project. But I hope that, by now, you started using C++11 features like many others projects did (Qt Creator, KDE, LLVM).

MSVC will enables C++14 by default with their new compilers, but clang and gcc require a special compilation flag (currently -std=c++1y). With qmake, you can enable your project to build with C++14 since Qt 5.4 by using this option:

CONFIG += c++14

What's New in Qt 5.4: The QStorageInfo Class

In this blog post, I will cover a new class introduced in Qt 5.4.0: QStorageInfo. This post is based on a Lightning Talk I gave at Qt Developer Days 2014 in San Francisco.

Overview

The QStorageInfo class provides information about mounted filesystems, also known as volumes. It allows retrieving information about a volume's storage space, mount point, label and filesystem name. New in the Qt 5.4.0 release, QStorageInfo is part of the Qt Core module.

Endocode is hiring an Assistant to the Board

If you are a recent or about to graduate in a Bachelor’s or Fachhochschule degree in business studies, Endocode might be looking for you! We are hiring an assistant to the board. Admittedly, the job is quite a challenge. It gives a sneak peek into all aspects and functions of managing a company. It does not require much experience, but it requires good training and a passion for learning and problem solving. The responsibilities include supporting management processes like board meetings and negotiations, and also some administrative work for relaxation.

Endocode

One interesting detail about the job is that it is ideal for gaining management and leadership skills before beginning a Master’s degree. I was told not many companies are offering interesting jobs for Bachelor graduates – well, we do! If you are interested, the details are on Endocode’s job page. Feel free to pass it on to your student and graduate friends. The deadline for applications is December 7.


Filed under: Coding, CreativeDestruction, English, FLOSS, KDE, OSS, Qt

HsQML 0.3.2.0 released: Enters the Third Dimension

Last night I released HsQML 0.3.2.0, the latest edition of my Haskell binding to the Qt Quick GUI library. As usual, it's available for download from Hackage.

HsQML allows you to bind declarative user interfaces written in QML against a Haskell back-end, but sometimes you can't just let QML hog all the graphical fun to itself. This latest release allows you incorporate 3D (OpenGL) graphics rendered from Haskell into your QML scenes using the new Canvas module.

The screenshot below shows off the OpenGL demo in the samples package. The colourful triangle is rendered using the regular Haskell Platform's OpenGL bindings, but HsQML sets up the environment so that it renders into a special HaskellCanvas element inside the QML scene. If you run the actual program you can see it being animated too, moving around and changing colour.


This release also adds the Objects.Weak module which allows you to hold weak references to QML objects and keep track of their life cycles using finalisers. The new FactoryPool abstraction uses these primitives to help you efficiently keep track of instances you've created, especially for when you need to fire change signals on them for data-binding.

London Haskell User Group

I've been fortunate enough to get a speaking slot at the London Haskell User Group and will be giving a talk on Building Pragmatic User Interfaces in Haskell with HsQML on the 26th of November. Please feel free to come along and watch. You can RSPV on the group's meet-up page.

The talk should be videoed and materials will be available online afterwards.

release-0.3.2.0 - 2014.11.13

* Added OpenGL canvas support.
* Added weak references and object finalisers.
* Added FactoryPool abstraction.
* Added To-only custom marshallers.
* Added Ignored type.
* Relaxed Cabal dependency constraint on 'text'.