The goal is to come up with a way to protect your QML code from plagiarism. It is a problem, since the way QML was designed and implemented seems to be inexplicably unprotected in this regard. The only QML types which are somewhat protected are those implemented entirely in C++.
- Qt resource files don't support any degree of protection
- even if you compress the resource file, extracting data from it is still fairly trivial to anyone with moderate experience
- QML files stored on the file system are practically there for the taking
- the same applies to any remote QML files, aside from adding dependency on internet connection, it is easy to sniff on the network access and get the QML files through their urls
- QML doesn't provide seem to provide any public API to allow users enough control over QML type resolution to protect their code
All in all, it almost looks like Qt deliberately skimps on QML code protection, one obvious candidate reason would be to force people into buying the insanely expressive commercial license, which features the QML compiler.
So absent any stock method of protecting QML sources, the only solution that currently comes to my mind is control over how QML types are resolved. There are several ways of registering types to QML:
- register in the application executable
- register in a plugin
- register via a QML module
However, what I need is to manually resolve QML types, much like you can create a custom QQuickImageProvider
which inputs a URL string and outputs an image, I need the QML engine to request a string with the type to my custom component provider which outputs a ready for object instantiation component.
This would be easy if any custom instantiation mechanism is used, but I need those types to be usable in regular QML sources. Ideally this should be the first mechanism used to resolve the type, before looking in the available import paths or even internally registered types.
Alternatively, it would be just as useful if there is a way to define a QML module entirely in C++, without any external QML files, without a qmldir
file and so on.
As a last resort, and falling short from ideally, I would also settle for registering QML (not C++) types to the runtime, this could also be useful, but I'd prefer to have full control over the resolving process.
A QML plugin does not do the trick, as it registers C++ types, and I want to register QML types, that is, QQmlComponent
s created from string sources and referencing each other.
QQmlComponent::setData
function. – PitreSomeType {...}
in QML and have manual control to associate "SomeType" to a QML component. – ShiffLoader { sourceComponent: someType1; ... (properties of the item) }
and changesourceComponent
to be pointing to the right component. Changing the meaning of theSomeType {}
doesn't look promising because the type id is determined at the QML compile time (kdab.com/qml-engine-internals-part-1-qml-file-loading). – PitreLoader
, the components need to be directly usable as QML types in sources. – ShiffqmlRegisterType(const QUrl &url, ...)
that allows to map a specific QML source file to the QML type? (before the load, of course) – Pitre