PDA

View Full Version : Mixed type data model and recursive structures in QML



gemmell
2nd February 2013, 11:01
I read another post by wysota about the suitability of QML and it has cast doubt over the future direction I want to take with my app.


If most of functionality of your application is related to dragging static objects on some canvas, setting their properties, doing things like copy & paste, undo&redo, etc. then QtQuick doesn't have much to offer in this regard. It's about DECLARING things to happen. You can't really predeclare situations that heavily depend on the logic. I'm not saying it is not possible to do what you want with QtQuick (see the link at the end of my post), I'm just saying it will probably take you much time without any real benefits.

http://www.youtube.com/watch?v=kvWeE3kurEQ


In my situation I have a tree model (implemented through QAbstractItemModel) where elements in the tree represent different types of elements. To simplify things, lets just say there's frames, and text. And I want to draw that in a QML scene.

So a frame can have other frames (hence the tree) and text (which is a leaf element). I've been musing on how to do this in QML for a while now - I was thinking I could get around the recursive nature of a tree by essentially proxying it and representing it as a list (and use different indents to make it look like a tree)... but then the type thing has me a bit stumped. I mean if you have an if statement in your delegate, are you trying to do something in a declarative language that isn't really declarative?

I think what wysota is saying is "Yo dude, it's a new technology, but it's not suitable for every use case".

So really, my questions are:

If I have a custom type which I can access via the QModelIndex/QAbstractItemModel data(MyRoles::dataRole), can I do a conditional on the type returned from that in the QML and draw totally different things (e.g. using a loader (http://www.qtcentre.org/threads/35816-Using-an-If-condition-in-a-QML-delegate))? Can I then do a QML equivalent of "dynamic_cast" to get the object I originally put in there and pull out it's data? I know that's kind of what data() is supposed to do, but it means you need a role for every property of every type...

Or is it the wrong technology to be using? Is the fact that I'd be putting in a conditional an indicator that it's not really suitable for a declarative language? Maybe I'd be better off doing something like this in HTML or a graphics scene? The fact that it doesn't really "do" tree's is certainly a warning flag for me.


EDIT: I want to make it quite interactive - reordering via drag/drop of frames etc, hence looking at these solutions.

wysota
2nd February 2013, 12:42
I think what wysota is saying is "Yo dude, it's a new technology, but it's not suitable for every use case".

Good point. Having a space rocket in your back yard is nice for a number of things but it will hardly help to bake cookies.


If I have a custom type which I can access via the QModelIndex/QAbstractItemModel data(MyRoles::dataRole), can I do a conditional on the type returned from that in the QML and draw totally different things (e.g. using a loader (http://www.qtcentre.org/threads/35816-Using-an-If-condition-in-a-QML-delegate))? Can I then do a QML equivalent of "dynamic_cast" to get the object I originally put in there and pull out it's data? I know that's kind of what data() is supposed to do, but it means you need a role for every property of every type...
You don't really need dynamic cast. If your model is built of QObjects, you can access any property of the object in your QML code. QML doesn't care about its type as long as it knows how to access the data. And it knows that for any QObject subclass that uses properties and slots.


Or is it the wrong technology to be using?
Well... as usual, it depens. If you want to have a tree displayed then I believe you can either transform it into a list, like you already said, or treat children of a node as a new list that you again display in a view. There is a number of implementations of a treeview for QML available in the net, maybe you'll find something you can adapt for your usecase. Besides that you can always implement a custom item type that will do what you want. If you're using Qt4 then you can even embed a real QTreeView in your QML scene (it's not that easy in QtQuick2/Qt5 though).


Is the fact that I'd be putting in a conditional an indicator that it's not really suitable for a declarative language?
No, it doesn't mean anything like that. QML is full of conditionals:

Rectangle {
color: ma.containsMouse ? "red" : "blue" // <--
MouseArea {
id: ma
anchors.fill: parent
hoverEnabled: true
}
}


Maybe I'd be better off doing something like this in HTML or a graphics scene? The fact that it doesn't really "do" tree's is certainly a warning flag for me.
I think it heavily depends on what you need apart that tree. If the tree is going to be your main area of focus, then I'd probably code it in C++ unless you can find a tree view implementation in QML that does what you want.