Embedded QML in qrc file

KDAB works on a lot of projects based on qml.
But sometime for specific applications it’s not safe to store directly qml file on file system.
As you know the QML files are plain text files.

For example if an user can have access to qml files he can change the logic of the application.
This is not critical for a application as  “Clock” but it can be critical in other domains.

So there is two methods to avoid it:

  • Using the Qt Resource for embedding the QML files (This blog will explain how to do).
  • Using the qtquickcompiler to generate a precompiled QML file (But a commercial license is needed)

The Qt Resource system allows to store a lot of data/binary files in executable directly.
Data can be an icon, a translation file, etc. and of course a QML file.

This blog will explain how to use it in a QML plugins implemented based on a QMLExtensionPlugins class.

For a standard application which uses some QML files this is very easy. We put them in a qrc file and we can access to it directly with a line as “view.setSource(QUrl(QStringLiteral(“qrc:/plugins.qml”)));”

We will see how to do it on a example based on qmlextensionplugins.

We adapted a qt qmlextensionplugins example (It’s the Clock example that you can find in qt source code) to create an little application.
Source code can be download here

It will display a clock.
The pro files were adapted to allow to install apps in “install” directory.
(qmake && make && make install).

When you look at install folder you can see all these files.

./plugins.qml
./extensionpluginsapps
./TimeExample/hour.png
./TimeExample/minute.png
./TimeExample/clock.png
./TimeExample/qmldir
./TimeExample/center.png
./TimeExample/libqmlqtimeexampleplugin.so
./TimeExample/Clock.qml
./TimeExample

=> As you see the QML files are stored on filesystem.

Now what we need to change for using Qt Resource ?

We will create a Qt Resouce file which will embed all qml files and icons.


<RCC>
<qresource prefix=”/clock”>
<file>Clock.qml</file>
<file>center.png</file>
<file>clock.png</file>
<file>hour.png</file>
<file>minute.png</file>
</qresource>
</RCC>

There is not a specific prefix.
And you just need to adapt qmldir for using a specific QtResource path (use qrc:///<path>)


module TimeExample
Clock 1.0 qrc:///clock/Clock.qml
plugin qmlqtimeexampleplugin

Of course the file qmldir can’t be stored in Qt Resource file otherwise  the application will not be able to  find plugin.

As you see now the list of files in install directory is limited to:

./extensionpluginsapps
./TimeExample/qmldir
./TimeExample/libqmlqtimeexampleplugin.so
./TimeExample

(of course I stored plugins.qml in another qrc file).

So the application is more safe now.

You can get source code here

Trackback

3 comments untill now

  1. How has this become more safe?

    Cant you still just modify the qml using a suitable unpacker, like 7zip or is the ressource file not easily modified ?

    I would imaging you only need to change on header table and the actual file part.

    I guess there is no real downsides to it either.

  2. Very useful post. Thanks!
    How do we generate typeinfo file for QML component embedded into plugin? I could not make it work with \qmlplugindump\. I am willing to write typeinfo file but could not find any example for QML only component.

  3. Just in case anyone else is trying to do this and is having autocomplete issues:
    https://bugreports.qt.io/browse/QTBUG-48809

Add your comment now