Post by Alan AlpertPost by Alberto MardeganHi all!
I'd like to make C++ models more usable from QML; in the net there
are several blog posts illustrating how to achieve that, but IMHO it
would be better if at least some of these handy features were in
- "count" property
- "get(index)" invocable method, returning a QVariantMap mapping all the
roles to their data for the specified index
+1 from me, those would clearly make it more QML-friendly.
Post by Alberto Mardegan- "remove(index)" which just calls QAbstractItemModel::removeRow()
- "QList<QVariant> items(const QString &role)", which returns the data
for the role "role" for all items.
I'm on the fence about adding those. Since they wouldn't be commonly
used, maybe it would be better to wait until there's time for a more
holistic 'models in QML' update (which likely means waiting a long
while, but eventually QML and QtQuick will need to deal with the issue
of full tree model support).
Post by Alberto MardeganThe implementation for the above is fairly trivial, so I wonder if
there's some other reasons why it hasn't been done or if it's just that
no one did and a patch is welcome.
To my knowledge it's the latter. There's a lot of Qt API which could
be made more QML friendly, especially in this way (just adding
properties and convenience functions, for when a user subclass is
exposed to QML).
Funny this should be posted -- I'm coding a "wrapper" for a bunch of
app-specific QML/QAIM right now.
I assume we are all referencing Chris' blog post from two years ago:
http://cdumez.blogspot.com/2010/11/how-to-use-c-list-model-in-qml.html
...and Benoît's referencing blog from a year ago with some "extensions":
http://bsauts-en.blogspot.com/2011/09/listmodel-in-c-exposed-to-qml.html
...and stuff like QML "read/write (role)" updates:
http://qt-project.org/forums/viewthread/21787/
...and making a "model" a property of an item within another "model":
http://qt-project.org/forums/viewthread/6906
There's not tons of C++QAIM/QML blog posts out there, so please jump in if
you know of others. Generally, I'm trying to understand
"accepted-convention" regarding these, and implement my "template-wrappers"
which look like:
QAbstractItemModel
=> (derive) MyItemModel (abstract with signals/slots/properties)
=> (derived) MyItemModelBase<> (template with app-specific hooks
possible)
=> (derived) MyAppSpecificModel (many of these)
This is a pattern I've used quite a lot with Qt (others have also), and it
works:
- MyItemModel implements stuff I always want "extended", has
signals/slots/properties, and runs through "moc"
- MyItemModelBase<> does NOT run through "moc" (it's a template, you
can't), but has common implementation that may be "overridden" in
application-specific-type-derived-cases. (Derived classes merely override
the MyItemModelBase<>::SomeFunc())
- MyAppSpecificModel - may run through "moc", but usually I don't need
additional "signals/slots/properties" (anything needed was commonly
provided in "MyItemModel").
What's interesting about the QAIM/QML thing (to me) is abstracting the
concept of the "Item-within-the-Model" with "properties/roles" exposed to
QML. Chris' example illustrated this with his "ListItem" (derived from
"QObject"). But, I think it would more generically be handled with that
common pattern I tend to use:
QObject
=> MyModelItem (with "signals/slots/properties")
=> MyModelItemBase<> (template, no "moc")
=> MyAppSpecificItem (many of these)
QUESTION: Alan seems to suggest the (C++) QAIM/QML might be
changed/updated in the "near-future" (and that was the purpose for the
question in this thread). Is that to handle the "model" or the "item", or
"both"?
QUESTION #2: I *assumed* (perhaps wrongly) that QAbstractItemModel DID NOT
have "Q_PROPERTY()" things because the "Q_PROPERTY()" is purported to
expose attributes to QML. I see "Q_PROPERTY()" as an "adapter-to-QML".
So, it seemed obvious (to me) that all "Q_PROPERTY()" things would go into
"MyItemModel", and not the "QAbstractItemModel" itself. Any
"common-properties" (like "count()" and "get(int)") could similarly be in a
derived "QAbstractItemModelWrappedForQml". Is the intent to make it
"open-season" on adding "Q_PROPERTY" things to other C++ classes, for those
attributes to be exposed to QML? I'm not sure that's a good idea, because
it seems like the "act-of-wrapping/exporting" to QML is a very different
level API than the act of C++ interfacing with the primitive C++ class.
(This isn't a strongly held view, it's just my current impression.)
An additional design need I have is for "generic-sets-of-things" to be
"referenced" by "MyAppSpecificModel" instances, so that adding/changing the
"set" is "reflected" in the QML. I'm pretty sure this can be implemented
in a generic fashion with the pattern listed above. I wouldn't do this
work, or I would "retire" this work, if Qt-proper were going to take that
on. My specific work is for these design goals:
- App-specific "model" that "reflects" the "set-of-app-specific-items"
(with all relevant "updates" into QML when an item-in-the-set-changes)
- App-specific "model" is implicitly composed of app-specific "items" with
their own unique "roles/properties" exposed to QML (very important so QML
delegates can be written)
- App-specific "model" is defined with only a few lines of code (e.g.,
derive from template-base)
Is anyone else doing work like this? For example, I could consider using
classes like:
- QAbstractItemList
=> QAbstractItemListWithQmlProperties (FICTITIOUS)
- QItemForModelExposedToQml (FICTITIOUS)
...although I use templates quite a lot as the "base" class because the
"re-use" is higher, and the implementation does not go through virtual
functions. (This pattern is done by me and others, but is not commonly
seen within the Qt code base itself.)
--charley