Qt QML Hot Tips #7
Mike Trahearn
Qt Champion??????, Qt QML C++ Specialist, Director, Codecept Software Pty Ltd; A Unique Thinker, Detailed Craftsman with Precise Foresight and a Personal Approach
Part 7 - Does my RCC look BIG in this?
Or, "How to handle your large assets"....
How does one answer that tactfully? ;-)
Have you ever stuffed your QRC face with chubbyBunnies.gif or donutEatingComp.mov or anything else that instantly bloats out your sugar-laden resources and kills your compile time or even just kills your compiler?
A real example might be adding unicode fonts which can be quite large or a set of images for the Qt Quick Controls Imagine Style or sets of multi-resolution images for large retina displays. These can make some compilers fall over or, if they don't, they take an age to crunch through the bits.
Fortunately Qt has a solution: you can use RCC to embed and compile your big files as part of a two-step process which not only gets past the compiler limitation problems, it is magnitudes faster!
QMake Solution
CONFIG += resources_big
# yeah, not big_resources... hmm
That's it, barring a possible call to Q_INIT_RESOURCE(yourResource) if you need to - there are cases where you don't.
But what about CMake? That's where it gets a little more interesting - and fun!
CMake Solution
Before I go on, I'll assume familiarity with QML Modules as per Qt 6.2 onwards and using Qt 6.5 and CMake 3.23 although the solutions here are not limited to QML Modules.
To start with, here's a quick example of a testApp with a QML Module carrying a large file in its RESOURCES:
qt_add_executable(testApp
main.cpp
)
qt_add_qml_module(testApp
??URI TestApp
??AUTO_RESOURCE_PREFIX # :/qt/qml
??VERSION 1.0
?QML_FILES
?? main.qml
??RESOURCES
???? MassiveUnicodeFont.otf
)
The compiler will crawl over the font as it tries to pull in the file into the QML Module's resources. So long as you don't need to do that too often, this works, but as you add more and more QML files, your incremental build time for a one line change will include recompiling that big font over and over again since it is in the same generated QRC file as the QML files. That's if your compiler doesn't die trying when it runs out of space processing the file.
Solution 1: Place your big files in a separate QRC file and process it separately.
This results in the following CMake code:
领英推荐
qt_add_executable(testApp
main.cpp
)
qt_add_big_resources(FONTS_LARGE_RESOURCES
fonts_large_resources.qrc
)
list(APPEND FONTS_LARGE_RESOURCES
fonts_large_resources.qrc
)
set_source_files_properties(
fonts_large_resources.qrc
PROPERTIES
SKIP_AUTORCC ON
)
qt_add_qml_module(testApp
??URI TestApp
??AUTO_RESOURCE_PREFIX # :/qt/qml
??VERSION 1.0
SOURCES
? ${FONTS_LARGE_RESOURCES}
?QML_FILES
?? main.qml
)
# Q_INIT_RESOURCE(fonts_large_resource) required in the source code
Solution 2: Target Based Approach
In my view, Solution 1 contains far too many steps which are all trying to get things to do what we want.
However I offer you Solution 2 and the reason for this Qt QML Hot Tips!
Start with the following simple setup:
qt_add_executable(testApp
main.cpp
)
qt_add_qml_module(testApp
??URI TestApp
??AUTO_RESOURCE_PREFIX # :/qt/qml
??VERSION 1.0
?QML_FILES
?? main.qml
)
Then we add the magic:
qt_add_resources(testApp "testApp_large_resources"
??PREFIX /qt/qml/TestApp
??BIG_RESOURCES
??FILES
????MassiveUnicodeFont.otf
)
That's it. Really!
The above adds additional resources to the target "testApp", gives it a name (for code generation), tells RCC to use the BIG_RESOURCES two-step process over the specified FILES and builds them into your binary already initialised.
FOUR nice big DO-NOTs and whole heap of icing!
Better than a box of Krispy-Kremes.
Summary
qt_add_resources( <target> ... BIG_RESOURCES) gives you a really simple way to separate your big resources in your CMake file in one well organised place and get all the benefits of faster compiler time, auto initialisation and a much better development experience without having to do any the work!
Happy cake eating!
Qt Champion??????, Qt QML C++ Specialist, Director, Codecept Software Pty Ltd; A Unique Thinker, Detailed Craftsman with Precise Foresight and a Personal Approach
1 年As of Qt 6.5 AUTO_RESOURCE_PREFIX is gone and you need to make the following well explained slight adjustments - which, if you read well enough, are big enablers! https://www.qt.io/blog/whats-new-for-qml-modules-in-6.5 Additionally, the added resource command could share a common variable for the resource prefix with the target's resource prefix to avoid duplication and possible error.