On Tue, Dec 11, 2012 at 5:27 PM, Jan Kundrát <[email protected]> wrote:
> On Tuesday, 11 December 2012 04:23:51 CEST, Alan Alpert wrote:
>> For finer-grained control over QML it would make sense to have an API
>> allowing import restrictions. Two usecases come to mind, platform
>> security contexts and scriptable applications.
>
> I'm currently using QML as a configuration language (being declarative looked
> like a great fit) in a random application. The end goal was to have one file
> per supported "type of thing" that the application works on. The description
> of each thing looks like this:
>
> import foo.bar 1.0
>
> ThingType {
> // ...
> SubThing {
> // ...
> }
> }
>
> Because I'm stuck on 4.x for this particular application, I had to work with
> what is available now. In the end, I settled on:
>
> - Using just a QDeclarativeEngine as a good start -- no need for UI items in
> my use case
>
> - The ThingType and SubThing are actually implemented in C++
>
> - Enforcing that the top-level item created in QML is exactly the ThingType.
> This can be done when instantiating the component by checking its type via
> qobject_cast<QMLMyTypeThing*> and refusing to work with that QML file if this
> cast fails
This doesn't completely fix the problem, because if the wrong thing is
instantiated it will still be able to do things in the period while
and just after it is instantiated. For example there could be side
effects from them instantiating a different type which you exposed,
and they could still do stuff in the Component.onCompleted handler.
>
> - The ThingType has a QDeclarativeListProperty<QMLMySubThing> Q_PROPERTY
> which is also a default property. This way, the type of the children of the
> ThingType is enforced.
Actually this isn't enforcing the type of the children. That property
has its type enforced, but properties can be dynamically added in QML.
For example
import foo.bar 1.0
import QtQuick.Window 1.0 //Hypothetical back-port of QtQuick.Window to 4.x
ThingType {
SubThing {}
property Window window: Window { } //This will create a window
}
Being able to dynamically add properties is a core part of the
language and I think it would be far, far better to restrict the types
available than to try to disable dynamic properties for some objects.
>
> - If you need further enforcing of certain rules ("each ThingType has to be
> yellow"), you can inherit from QDeclarativeParserStatus and implement
> componentComplete. My code works like this:
>
> if (!m_color.isYellow())
> qmlInfo(this) << "The color must be yellow."
>
> - Because these errors are only warnings (and it looks like you cannot really
> trigger a fatal error from this stage), I have an isOk() method which I call
> before I use the data structure which gets created as a result of these QML
> files.
>
> If it was possible to prevent defining the QtQuick namespace from being
> available, that would solve half of my problems (with the required property
> validation being the remaining half).
Property validation within an item will always have to be done by the
item, so that's the best we'd be able to do.
> The blurb about qmlInfo() was in particular rather hard to discover -- I had
> read the docs about it before but could not recall the name of the function
> when I needed it. Searching for it via phrases like "qml error reporting" did
> not help much.
It's not one of the most public functions in QML. But there should
probably be a mention of it on the page about writing QML types in
C++, if anyone wants to try writing that.
--
Alan Alpert
_______________________________________________
Development mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/development