How to resolve C++ Component naming conflicts in QML
By: Brad
In this tutorial I’ll show you how to resolve Naming conflicts between C++ Components within a QML script.
Lets say your importing two separate models (ca.imaginativethinking.tutorial.objectone
and ca.imaginativethinking.tutorial.objecttwo
) and lets assume they are from two different third party vendors which you have little control over. Now what happens if they both contain a component which has the same name.
qmlRegisterType<ObjectOne>("ca.imaginativethinking.tutorial.objectone", 1, 0, "MyObject"); qmlRegisterType<ObjectTwo>("ca.imaginativethinking.tutorial.objecttwo", 1, 0, "MyObject");
Lets assume through libraries that your linking against the above code is run which registers two objects (ObjectOne
and ObjectTwo
) with the same QML keyword name (MyObject
) within two separate modules. Now if you never imported these two modules within the same QML script then you don’t have any issues but what if you wanted to use both these objects (or one of these object and another object which is also within one of these two modules) in the same QML script? Your going to have a naming conflict. When you declare MyObject {...}
the QML engine won’t know which object you meant to instantiate.
The QML engine can not import two components with the same name into the same namespace.
When the QML engine processes a QML script it reads it line by line going from top to bottom. If your script imports ca.imaginativethinking.tutorial.objectone
first then imports ca.imaginativethinking.tutorial.objecttwo
the engine will first register ObjectOne
with the name MyObject
then it will register ObjectTwo
with the name MyObject
effectively un-registering ObjectOne
.
import ca.imaginativethinking.tutorial.objectone 1.0 import ca.imaginativethinking.tutorial.objecttwo 1.0 //Would be ObjectTwo not ObjectOne. MyObject{ id: objectOne }
So How can I use both ObjectOne and ObjectTwo in the same QML script?
The good news is that Qt didn’t leave you high and dry they have a built in mechanism to deal with naming conflicts.
When you import modules in your QML script all the components in the module are imported into a non-qualified local namespace. Think of the import statement as something similar to a combination of the #include<>
and using
statements in C++. In C++ you deal with naming conflicts by putting your classes into different qualified namespaces; when you include a class you need to access the class by qualifying which namespace your intending to use. Of course typing std::string
over and over again is a pain so C++ also has a using
statement where you can tell the compiler that within this file scope put all the classes into a local non-qualified namespace so that when you see string
know to use std::string
. Its a nicety to save typing and where C++ made that an opt-in nicety QML made it an opt-out. The import statement in QML by default puts all the imported components into a non-qualified local namespace so that you can access any of the components within the module without qualification.
Most of the time this work without issues and lets you write your QML script with far less typing but in the above case its landed us in a naming conflict problem. To resolve this you can tell the import statement to place the components into a qualified local namespace instead by using the as keyword.
import ca.imaginativethinking.tutorial.objectone 1.0 as ObjectOne import ca.imaginativethinking.tutorial.objecttwo 1.0 as ObjectTwo
By adding the as
keyword and a qualification name to your script you can now explicitly state which module you intend to use.
import ca.imaginativethinking.tutorial.objectone 1.0 as ObjectOne import ca.imaginativethinking.tutorial.objecttwo 1.0 as ObjectTwo ObjectOne.MyObject { id: objectOne } ObjectTwo.MyObject { id: objectTwo }
So there you go that is how you can resolve naming conflicts between C++ Modules.
You can download a sample application which illustrate the above here:
Naming Conflict Sample 1: QML Component Conflicts
Naming Conflict Sample 2: C++ Component Conflicts
Here is where you can find the official Qt documentation on the import statement
Thank you I hope you have enjoyed and found this tutorial helpful. Feel free to leave any comments or questions you might have below and I’ll try to answer them as time permits.
Until next time think imaginatively and design creatively