KEMBAR78
Porting Qt 5 QML Modules to Qt 6 Webinar | PDF
Sub-Header Text
Welcome
1
www.ics.com
About ICS
Founded in 1987, ICS accelerates the
development of next-generation products through
cutting-edge software solutions and expert
engineering services.
● Headquarters in Waltham, MA (Greater
Boston area)
● Global presence with offices in California,
Canada, and Europe
● Team size of 160 professionals
● Expertise in embedded systems, UX/UI
design, and Qt/QML development working
in industries from medical devices and
commercial kitchen appliances to industrial
controls and in-vehicle infotainment
systems
● Leading independent source of Qt expertise
in North America.
Qt 6 “Partial
Ports”
Page #
● Qt 5 and Qt 6 are quite source compatible
○ Or source tolerant with some warnings
○ Make sure depreciation warnings are not turned off
● Many project can “just compile” against Qt 6
○ Some need a few light source changes
● Many of the above projects “just work”
○ Some will need QML runtime code changes
● QMake lives on in Qt 6, but is deprecated
○ Port to CMake
● Old QML modules are still valid and not deprecated
○ Warnings will not be printed for using them
○ Port to Qt 6 style QML modules! So much easier!
Qt 5 and Qt 6 Source Compatibility
4
● Hand writing QML Modules (qmldir, qmltypes, qrc, plugin files) is still supported in Qt 6
○ Qt 6 has built an entire automation layer on top of these features
■ Your life will be so much easier if you use it!
■ If you haven’t used QML modules consider doing so
● No more extra typing and annoyance if you miss a step!
● It is a small misnomer to call the newer modules Qt 6 Style
○ Many of the automation features are available in Qt 5.15 when using CMake
○ “Modern QML Modules” is probably more appropriate
■ Or “Ancient QML Modules” for the Qt 5 Style
● Given how long Qt 6 has been released.
○ 5 years already!
QML Module Automation in Qt 5
5
● I wrote an example application in Qt 5 using QMake
○ Then ported it to Qt 6 using CMake and modern QML Modules
○ The sources will be available after the webinar is complete.
● I actually forgot what a pain the old modules are!
Example Application
6
Qt 5 Style QML
Modules
Page #
● Create a subdirectory with the same name as your module
○ Add plugin .pro
TEMPLATE = lib
CONFIG += qt plugin
QT += qml quick
SOURCES += 
mysingleton.cpp 
plugin.cpp
HEADERS += 
mysingleton.h 
plugin.h
QML_FILES += 
qmldir 
CustomGraphicsItem.qml
Creating A Module
8
● Deployment of QML Modules has historically been a hassle
○ Copying files to build dir / install dir
○ Embedding files in .qrc files
■ Automatic qrc embedding when using the Qt Quick Compiler
# Install QML files
qmlfiles.files = $$QML_FILES
qmlfiles.path = $$OUT_PWD
INSTALLS += qmlfiles
Add INSTALL Target
9
● For better syntax completion in Qt Creator
○ This as optional and often never got implemented at all
■ Once upon a time it was a “by hand process”
CONFIG += qmltypes
QML_IMPORT_NAME = MyComponents
QML_IMPORT_MAJOR_VERSION = 1
Generate QML Type Meta Data
10
module MyComponents
plugin MyComponents
classname MyComponentsPlugin
typeinfo mycomponents.qmltypes
CustomGraphicsItem 1.0 CustomGraphicsItem.qml
Add qmldir Manifest File
11
class MyComponentsPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
void registerTypes(const char *uri) override;
};
void MyComponentsPlugin::registerTypes(const char *uri)
{
// Register the singleton
qmlRegisterSingletonType<MySingleton>(uri, 1, 0, "MySingleton",
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
return new MySingleton();
});
}
Add Plugin Class
12
● QML2_IMPORT_PATH env var needs to include the build or install directory of the module
○ For the application to work at runtime
● QML_IMPORT_PATH qmake var need to include the source directory
○ For Qt Creator to give reliable syntax completion
Update Qml Import Paths
13
● Because building and deploying modules was tricky often
○ Developers did not use QML modules
■ Stuck with importing directories for organization
○ Developers short circuited the plugin and built everything in a traditional shared object
■ Easier deployment, but even more code.
QML Modules Embedded into Libraries
14
● QML files in located in a qrc of a shared object project
○ Shared library has an init function
■ Calls Q_INIT_RESOURCE(uniquename)
■ Registers the QML types like a plugin
● Main function in application needs
○ Call init on the library
○ Add :/ in the qml import path
● In the example there is a link_module config option that will show what these project look like.
Embedded QML Modules
15
● Add qml or source/header to .pro
● Add qml or singleton to qmldir
● Edit the plugin.cpp to register the singleton
● Add qml file to .qrc
● Make sure qmltypes metadata is up to date
● Missing any of the above (or mistyping a uri) causes annoying runtime errors
● Enough history and on to the future!
To add a new file we might have to …
16
Modern QML
Modules
Page #
● Qt’s C++ API has always favored a rich API with convenience functions
○ If everyone does it there should be a function for it.
■ Or at least as few lines as possible
● Philosophically this is why QString has a much more robust API than the standard library
○ See QString replace vs std::string replace
○ The standard library favors fewer functions that are used together
● That same philosophy has been applied to QML plugins
○ If all these qmldir files are the same can’t they be deduced from the project and source?
■ Qt is predicated on generated code. (moc is amazing)
○ Same for the plugin files.
■ They all look the same and we all used to stab in the same contents for every new
C++ implemented QML item.
● The modern QML plugins generate as much of the boiler plate as possible.
Qt is usually very convenient
18
● Old Style QML Modules are not deprecated
○ Modern QML Modules uses the same classes and functions as Old QML Modules
○ Modern QML Modules are an exercise in automation
● Use newer style modules in 5.15, then port to 6
○ There are still some differences between 5.15 LTS and 6.8 LTS, but manageable
○ Turn on all deprecation warnings and make those changes
■ Generally good porting advice for a 5 - 6 port.
● Port to Qt 6 first using the old style modules
○ The move to the new style modules
○ Most ports are done this way.
■ Mostly because it gets the project to Qt 6 faster
● Very important now that Qt 5.15 is no longer supported
Porting Strategy
19
cmake_minimum_required(VERSION 3.16)
qt_add_qml_module(MyComponents
URI "MyComponents"
VERSION 1.0
IMPORTS
QtQuick
QML_FILES
CustomGraphicsItem.qml
SOURCES
mysingleton.h
mysingleton.cpp
RESOURCES
images/up_arrow.png
)
target_link_libraries(MyComponents PRIVATE
Qt6::Core
Qt6::Quick
)
Use new Qt CMake functions
20
● There are many options that can be passed to turn how modules are generated
● Output directories, target names, etc
○ RESOURCE_PREFIX, OUTPUT_DIRECTORY, PLUGIN_TARGET
● Opt out of some generation. Might be useful if you have working handwritten files.
○ NO_GENERATE_PLUGIN_SOURCE, NO_GENERATE_QMLDIR,
NO_GENERATE_EXTRA_QMLDIRS
● QML Cache Options (Useful for QML hot reloaders)
○ NO_CACHEGEN
● QML Type Compiler Options
○ ENABLE_TYPE_COMPILER, TYPE_COMPILER_NAMESPACE, QMLTC_EXPORT_DIRECTIVE
qt_add_qml_module Options
21
● C++ classes used in QML need to be tagged as such. Similar to Q_PROPERTY
○ QML_ELEMENT = Instance-able in QML
○ QML_SINGLETON = Singleton in QML
class MySingleton : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(int counter READ counter NOTIFY counterChanged)
Q_PROPERTY(QString applicationName READ applicationName CONSTANT)
public:
explicit MySingleton(QObject *parent = nullptr);
Q_INVOKABLE void resetCounter();
Q_INVOKABLE QString formatMessage(const QString &message);
signals:
void counterChanged();
};
Add QML_ELEMENT and QML_SINGLTON
22
● Remove plugin h./.cpp
○ This is now generated automatically
● Remove .qrc file(s)
○ This is now generated automatically
● Remove qmldir files
○ This is now generated automatically
● Remove qmltypes file
○ This is now generated automatically
● Remove addImportPath calls from main
○ If your are OK with the Qt default resource prefix
■ When done right your module shouldn’t depend on the prefix
Make liberal use of the Delete key
23
● You many notice warnings about Qt Policy.
○ Set you policy to the minimum version of Qt you want to support
○ Using the CMake function
■ qt_standard_project_setup(REQUIRES 6.8)
■ You need to set this per CMake project
● Which is different than target or subdirectory to CMake
● In the example I set it once in the toplevel CMakeLists.txt
● There are subtle differences in the generated module code between version of Qt
○ 5.15 = QML modules default resources prefix is “:/”
■ This is the default if you don’t call qt_standard_project_setup at all
● Or a call it without a REQUIRED version number >=6.0
○ 6.0+ = QML modules default resources prefix is “:/qt/qml/”
Use most recent Qt Policies
24
Application
Modules
Page #
● Automatically generated .qrc resources file
○ This alone is really nice
● Automatic registration of QML items
● Automatic registration of QML singletons
● Qt Creator’s “New Qt Quick Project” generates new projects this way
Using Modules in Applications
26
● One CMakeLists.txt can create multiple targets (ex. a library and an executable)
○ This is a trick qmake couldn’t do
cmake_minimum_required(VERSION 3.16)
qt_add_executable(Application
main.cpp
)
qt_add_qml_module(Application
URI Application
VERSION 1.0
QML_FILES
Main.qml
)
target_link_libraries(Application PRIVATE
Qt6::Core
Qt6::Quick
Qt6::QuickControls2
)
One CMakeLists.txt with Multiple Targets
27
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
&app, []() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("Application", "Main");
return app.exec();
}
Load Main.qml From Module
28
● Use QML_ELEMENT and C++ classes are instance-able in QML
● Use QML_SINGLETON and C++ classes can be instanced as singletons QML
○ As long as these are traditional QML singletons
■ No construction parameters
■ Can be created and destroyed by QML Engine
● Non-trivial singletons need a little works
○ Often they are singletons to QML, buu have a stack/heap lifetime in C++
■ They simply outlive the QML Engine
Same as Library Modules
29
● Do not use context properties anymore
○ engine->setContextProperty(“MyThing”, &thing);
○ Performance issues
○ They are also the QML equivalent to global variables
● Do not use qmlRegisterSingletonType()
○ This requires some abuse to work with objects with a C++ drive lifecycle
● Use qmlRegisterSingletonInstance
○ Expects object to live longer than QML
○ One line. No need for a funky lamda.
● Use QQmlApplication engine to set initial properties
○ Like context properties, but more efficient
Exposing C++ Objects to QML
30
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
…
RobotController robot(communicationsController, sensors); // Non-trivial constructor
QmlEngine::setObjectOwnership(&robot, QQmlEngine::CppOwnership);
qmlRegisterSingletonType<MySingleton>(“Application”, 1, 0, "Robot",
[&](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return &robot;
});
…
}
Old C++ Driven Singletons
31
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
…
RobotController robot(communicationsController, sensors); // Non-trivial constructor
qmlRegisterSingletonInstance<RobotController >(“Application”, 1, 0, "Robot");
…
}
New C++ Driven Singletons
32
● Sometime context properties were used for some pretty trivial things
○ For example: Running on desktop or embedded device
■ One get a window, other gets full screen attributes
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
#ifdef Q_PROCESSOR_ARM
engine.setContextProperty(“isDesktop”, true);
#else
engine.setContextProperty(“isDesktop”, false);
#endif
…
}
Old Trivial Context Properties
33
● Sometime context properties were used for some pretty trivial things
○ For example: Running on desktop or embedded device
■ One get a window, other gets full screen attributes
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
bool isDesktop = true;
#ifdef Q_PROCESSOR_ARM
isDesktop = false;
#endif
…
// Set initial properties instead of context properties.
engine.setInitialProperties({
{ "isDesktop", isDesktop },
// Any other properties here
});
}
New Initial Properties
34
Questions and
Answers!
Page #

Porting Qt 5 QML Modules to Qt 6 Webinar

  • 1.
  • 2.
    www.ics.com About ICS Founded in1987, ICS accelerates the development of next-generation products through cutting-edge software solutions and expert engineering services. ● Headquarters in Waltham, MA (Greater Boston area) ● Global presence with offices in California, Canada, and Europe ● Team size of 160 professionals ● Expertise in embedded systems, UX/UI design, and Qt/QML development working in industries from medical devices and commercial kitchen appliances to industrial controls and in-vehicle infotainment systems ● Leading independent source of Qt expertise in North America.
  • 3.
  • 4.
    ● Qt 5and Qt 6 are quite source compatible ○ Or source tolerant with some warnings ○ Make sure depreciation warnings are not turned off ● Many project can “just compile” against Qt 6 ○ Some need a few light source changes ● Many of the above projects “just work” ○ Some will need QML runtime code changes ● QMake lives on in Qt 6, but is deprecated ○ Port to CMake ● Old QML modules are still valid and not deprecated ○ Warnings will not be printed for using them ○ Port to Qt 6 style QML modules! So much easier! Qt 5 and Qt 6 Source Compatibility 4
  • 5.
    ● Hand writingQML Modules (qmldir, qmltypes, qrc, plugin files) is still supported in Qt 6 ○ Qt 6 has built an entire automation layer on top of these features ■ Your life will be so much easier if you use it! ■ If you haven’t used QML modules consider doing so ● No more extra typing and annoyance if you miss a step! ● It is a small misnomer to call the newer modules Qt 6 Style ○ Many of the automation features are available in Qt 5.15 when using CMake ○ “Modern QML Modules” is probably more appropriate ■ Or “Ancient QML Modules” for the Qt 5 Style ● Given how long Qt 6 has been released. ○ 5 years already! QML Module Automation in Qt 5 5
  • 6.
    ● I wrotean example application in Qt 5 using QMake ○ Then ported it to Qt 6 using CMake and modern QML Modules ○ The sources will be available after the webinar is complete. ● I actually forgot what a pain the old modules are! Example Application 6
  • 7.
    Qt 5 StyleQML Modules Page #
  • 8.
    ● Create asubdirectory with the same name as your module ○ Add plugin .pro TEMPLATE = lib CONFIG += qt plugin QT += qml quick SOURCES += mysingleton.cpp plugin.cpp HEADERS += mysingleton.h plugin.h QML_FILES += qmldir CustomGraphicsItem.qml Creating A Module 8
  • 9.
    ● Deployment ofQML Modules has historically been a hassle ○ Copying files to build dir / install dir ○ Embedding files in .qrc files ■ Automatic qrc embedding when using the Qt Quick Compiler # Install QML files qmlfiles.files = $$QML_FILES qmlfiles.path = $$OUT_PWD INSTALLS += qmlfiles Add INSTALL Target 9
  • 10.
    ● For bettersyntax completion in Qt Creator ○ This as optional and often never got implemented at all ■ Once upon a time it was a “by hand process” CONFIG += qmltypes QML_IMPORT_NAME = MyComponents QML_IMPORT_MAJOR_VERSION = 1 Generate QML Type Meta Data 10
  • 11.
    module MyComponents plugin MyComponents classnameMyComponentsPlugin typeinfo mycomponents.qmltypes CustomGraphicsItem 1.0 CustomGraphicsItem.qml Add qmldir Manifest File 11
  • 12.
    class MyComponentsPlugin :public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: void registerTypes(const char *uri) override; }; void MyComponentsPlugin::registerTypes(const char *uri) { // Register the singleton qmlRegisterSingletonType<MySingleton>(uri, 1, 0, "MySingleton", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { return new MySingleton(); }); } Add Plugin Class 12
  • 13.
    ● QML2_IMPORT_PATH envvar needs to include the build or install directory of the module ○ For the application to work at runtime ● QML_IMPORT_PATH qmake var need to include the source directory ○ For Qt Creator to give reliable syntax completion Update Qml Import Paths 13
  • 14.
    ● Because buildingand deploying modules was tricky often ○ Developers did not use QML modules ■ Stuck with importing directories for organization ○ Developers short circuited the plugin and built everything in a traditional shared object ■ Easier deployment, but even more code. QML Modules Embedded into Libraries 14
  • 15.
    ● QML filesin located in a qrc of a shared object project ○ Shared library has an init function ■ Calls Q_INIT_RESOURCE(uniquename) ■ Registers the QML types like a plugin ● Main function in application needs ○ Call init on the library ○ Add :/ in the qml import path ● In the example there is a link_module config option that will show what these project look like. Embedded QML Modules 15
  • 16.
    ● Add qmlor source/header to .pro ● Add qml or singleton to qmldir ● Edit the plugin.cpp to register the singleton ● Add qml file to .qrc ● Make sure qmltypes metadata is up to date ● Missing any of the above (or mistyping a uri) causes annoying runtime errors ● Enough history and on to the future! To add a new file we might have to … 16
  • 17.
  • 18.
    ● Qt’s C++API has always favored a rich API with convenience functions ○ If everyone does it there should be a function for it. ■ Or at least as few lines as possible ● Philosophically this is why QString has a much more robust API than the standard library ○ See QString replace vs std::string replace ○ The standard library favors fewer functions that are used together ● That same philosophy has been applied to QML plugins ○ If all these qmldir files are the same can’t they be deduced from the project and source? ■ Qt is predicated on generated code. (moc is amazing) ○ Same for the plugin files. ■ They all look the same and we all used to stab in the same contents for every new C++ implemented QML item. ● The modern QML plugins generate as much of the boiler plate as possible. Qt is usually very convenient 18
  • 19.
    ● Old StyleQML Modules are not deprecated ○ Modern QML Modules uses the same classes and functions as Old QML Modules ○ Modern QML Modules are an exercise in automation ● Use newer style modules in 5.15, then port to 6 ○ There are still some differences between 5.15 LTS and 6.8 LTS, but manageable ○ Turn on all deprecation warnings and make those changes ■ Generally good porting advice for a 5 - 6 port. ● Port to Qt 6 first using the old style modules ○ The move to the new style modules ○ Most ports are done this way. ■ Mostly because it gets the project to Qt 6 faster ● Very important now that Qt 5.15 is no longer supported Porting Strategy 19
  • 20.
    cmake_minimum_required(VERSION 3.16) qt_add_qml_module(MyComponents URI "MyComponents" VERSION1.0 IMPORTS QtQuick QML_FILES CustomGraphicsItem.qml SOURCES mysingleton.h mysingleton.cpp RESOURCES images/up_arrow.png ) target_link_libraries(MyComponents PRIVATE Qt6::Core Qt6::Quick ) Use new Qt CMake functions 20
  • 21.
    ● There aremany options that can be passed to turn how modules are generated ● Output directories, target names, etc ○ RESOURCE_PREFIX, OUTPUT_DIRECTORY, PLUGIN_TARGET ● Opt out of some generation. Might be useful if you have working handwritten files. ○ NO_GENERATE_PLUGIN_SOURCE, NO_GENERATE_QMLDIR, NO_GENERATE_EXTRA_QMLDIRS ● QML Cache Options (Useful for QML hot reloaders) ○ NO_CACHEGEN ● QML Type Compiler Options ○ ENABLE_TYPE_COMPILER, TYPE_COMPILER_NAMESPACE, QMLTC_EXPORT_DIRECTIVE qt_add_qml_module Options 21
  • 22.
    ● C++ classesused in QML need to be tagged as such. Similar to Q_PROPERTY ○ QML_ELEMENT = Instance-able in QML ○ QML_SINGLETON = Singleton in QML class MySingleton : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON Q_PROPERTY(int counter READ counter NOTIFY counterChanged) Q_PROPERTY(QString applicationName READ applicationName CONSTANT) public: explicit MySingleton(QObject *parent = nullptr); Q_INVOKABLE void resetCounter(); Q_INVOKABLE QString formatMessage(const QString &message); signals: void counterChanged(); }; Add QML_ELEMENT and QML_SINGLTON 22
  • 23.
    ● Remove pluginh./.cpp ○ This is now generated automatically ● Remove .qrc file(s) ○ This is now generated automatically ● Remove qmldir files ○ This is now generated automatically ● Remove qmltypes file ○ This is now generated automatically ● Remove addImportPath calls from main ○ If your are OK with the Qt default resource prefix ■ When done right your module shouldn’t depend on the prefix Make liberal use of the Delete key 23
  • 24.
    ● You manynotice warnings about Qt Policy. ○ Set you policy to the minimum version of Qt you want to support ○ Using the CMake function ■ qt_standard_project_setup(REQUIRES 6.8) ■ You need to set this per CMake project ● Which is different than target or subdirectory to CMake ● In the example I set it once in the toplevel CMakeLists.txt ● There are subtle differences in the generated module code between version of Qt ○ 5.15 = QML modules default resources prefix is “:/” ■ This is the default if you don’t call qt_standard_project_setup at all ● Or a call it without a REQUIRED version number >=6.0 ○ 6.0+ = QML modules default resources prefix is “:/qt/qml/” Use most recent Qt Policies 24
  • 25.
  • 26.
    ● Automatically generated.qrc resources file ○ This alone is really nice ● Automatic registration of QML items ● Automatic registration of QML singletons ● Qt Creator’s “New Qt Quick Project” generates new projects this way Using Modules in Applications 26
  • 27.
    ● One CMakeLists.txtcan create multiple targets (ex. a library and an executable) ○ This is a trick qmake couldn’t do cmake_minimum_required(VERSION 3.16) qt_add_executable(Application main.cpp ) qt_add_qml_module(Application URI Application VERSION 1.0 QML_FILES Main.qml ) target_link_libraries(Application PRIVATE Qt6::Core Qt6::Quick Qt6::QuickControls2 ) One CMakeLists.txt with Multiple Targets 27
  • 28.
    int main(int argc,char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.loadFromModule("Application", "Main"); return app.exec(); } Load Main.qml From Module 28
  • 29.
    ● Use QML_ELEMENTand C++ classes are instance-able in QML ● Use QML_SINGLETON and C++ classes can be instanced as singletons QML ○ As long as these are traditional QML singletons ■ No construction parameters ■ Can be created and destroyed by QML Engine ● Non-trivial singletons need a little works ○ Often they are singletons to QML, buu have a stack/heap lifetime in C++ ■ They simply outlive the QML Engine Same as Library Modules 29
  • 30.
    ● Do notuse context properties anymore ○ engine->setContextProperty(“MyThing”, &thing); ○ Performance issues ○ They are also the QML equivalent to global variables ● Do not use qmlRegisterSingletonType() ○ This requires some abuse to work with objects with a C++ drive lifecycle ● Use qmlRegisterSingletonInstance ○ Expects object to live longer than QML ○ One line. No need for a funky lamda. ● Use QQmlApplication engine to set initial properties ○ Like context properties, but more efficient Exposing C++ Objects to QML 30
  • 31.
    int main(int argc,char *argv[]) { QGuiApplication app(argc, argv); … RobotController robot(communicationsController, sensors); // Non-trivial constructor QmlEngine::setObjectOwnership(&robot, QQmlEngine::CppOwnership); qmlRegisterSingletonType<MySingleton>(“Application”, 1, 0, "Robot", [&](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return &robot; }); … } Old C++ Driven Singletons 31
  • 32.
    int main(int argc,char *argv[]) { QGuiApplication app(argc, argv); … RobotController robot(communicationsController, sensors); // Non-trivial constructor qmlRegisterSingletonInstance<RobotController >(“Application”, 1, 0, "Robot"); … } New C++ Driven Singletons 32
  • 33.
    ● Sometime contextproperties were used for some pretty trivial things ○ For example: Running on desktop or embedded device ■ One get a window, other gets full screen attributes int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; #ifdef Q_PROCESSOR_ARM engine.setContextProperty(“isDesktop”, true); #else engine.setContextProperty(“isDesktop”, false); #endif … } Old Trivial Context Properties 33
  • 34.
    ● Sometime contextproperties were used for some pretty trivial things ○ For example: Running on desktop or embedded device ■ One get a window, other gets full screen attributes int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; bool isDesktop = true; #ifdef Q_PROCESSOR_ARM isDesktop = false; #endif … // Set initial properties instead of context properties. engine.setInitialProperties({ { "isDesktop", isDesktop }, // Any other properties here }); } New Initial Properties 34
  • 35.