Supporting multiple component sets with a single QML codepase


Aside from the QtQuick Controls introduced in Qt 5.1, there exist many incompatible QtQuick component sets, such as:

  • Sailfish Silica
  • Ubuntu Touch components
  • Nemo Glacier UI components (once implemented)
  • QtComponents? ported to Qt5 on Nemo

If an application wants to look native without manually imitating the style of the platform, it should use the native component sets. As those sets are mutually incomapatible and there are no real conditional imports in QML, it basically means writing a separate UI for each component set. While writing QML is fast and porting from one component set to the other should generally be easy, this is not really a solution for an incrementally developed application, as it would mean that half a dozen UI forks would need to be kept in sync for every feature added or changed.


Fortunately, this can be solved by using a component abstraction layer and using per platform QML import path manipulation.

The component abstraction layer provides a common API, that can be used by the application. The API than maps to all the different platform specific component sets.

For each supported component set, there is a separate QML module translation the elements of the given component set to the unified API. On each platform, the corresponding abstraction module is added to QML import path.

All the abstraction module use the same name, so that the application can use something like this:

import UC 1.0 as uc

    text : "hello world"

On each platform, the application will load the same UC module, which will actually correspond to the abstraction module specific for the platform.


To debug this (or any other import related QML issues), just enable QML import debugging:


After this environmental variable is set, QML will start printing import debugging messages to standard output.

Last modified 11 years ago Last modified on Oct 27, 2013, 1:07:50 AM