[Interest] Value objects in QML context
charleyb123 at gmail.com
Mon Oct 7 20:11:01 CEST 2013
> Hey there,
> I couldn't find anything usefull in the internet, so I hope you can help
> me in a design question.
> I'm part of a project using QML for the UI. Since we have several value
> classes, we came across a problem with exposing this value objects into
> the QML context.
> Lets assume I have a class CLocation with member variables for Latitude
> and Longitude:
> class CLocation
> double Latitude() const;
> double Longitude() const;
> void setLatitude(const double latitude);
> void setLongitude(const double longitude);
> double m_latitude;
> double m_longitude;
> http://qt-project.org/doc/qt-5.0/qtcore/object.html#identity-vs-value is
> specificly saying, I should not derive from QObject for this kind of
> value classes.
> But how can I access this setters and getters now in QML? Lets say I
> have a QMap of cities with its CLocations.
> In C++ I would call QMap::value() to get the CLocation by the city name
> and call the getter or do something else with the object. In QML I can't
> to anything similar, because its not accessable in the QML context. Do I
> really have to wrap around a QObject derived class, to call the setters
> and getters or how is this meant to be? Did I maybe miss something? I'm
> sure the designers of QML had such use cases in mind and I'm just not
> recognize the easy solution.
> Limiting the access to QObjects only in an UI seems strange to me. I
> understand the technic behind with Qt Metatype system, but isn't that
> limiting alot? <snip>,
You raise very good points (review for the casual reader):
(1)- QObject instances are "identities" (typically don't clone/copy them)
(2)- Your "MyValue" classes are often used as "values", and do not derive
(3)- How to expose "MyValue" classes to QML, such as when "MyModel" has
containers of "MyValue" classes (currently not derived from QObject?)
There's a lot more to this topic, but let's keep this simple.
ISSUE: Two things are going on:
(A) You have an "existing implementation" that uses your classes (e.g.,
"CLocation"), and implementation-specific aggregates of them (e.g.,
"QMap<CCity,CLocation>"). This implementation makes sense, it's just that
these "primitives" do not derive from "QObject".
(B) You expose things to QML by deriving from "QObject" and exposing
Logically, these are SEPARATE things. They are (logically) not related.
They are design-and-technology implications based on design decisions that
were made for different purposes.
However, as you point out, IN A PRACTICAL SENSE, they *are* related. You
need to expose your practical existing implementation through the
QMetaObject type system to make it "visible" to QML.
We do this *a lot* (lots of primitive domain-specific value-classes that
map to embedded hardware). We created a "smart-pointer-like-thing" derived
from QObject that exposes our "value" classes:
class MyQmlCLocation : public QObject
// ... own or reference the "real" CLocation, we logically have
// ...expose properties which trigger get/set operations on
This works (well) for us. However, this is tedious: It is an
"adapter-layer" that merely exposes our domain-specific classes to QML, and
which properly handles value (or reference) ownership semantics. So, we
implemented a "code-generator" that does the heavy lifting. We use it for
"value-types" and "reference-types", because the implementation is pretty
much like a "smart-pointer" that owns-or-references the target.
I'm sure there are other ways to do this, but I don't think there is a
practical alternative to creating this "adapter-layer" for exposing your
domain-specific classes to QML.
I'll be talking about our approach at Qt Dev-Days San Francisco, if you are
around, and I assume the organizers will make the slides and presentation
Also -- I'm very interested in how other people are solving your very
practical question. (Good ideas are always welcome.)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Interest