5 oct 2010
this posting is about using a QGraphicsScene/QGraphicsView with a QAbstractItemModel. i’ve blogged about this two times, see [1] and [2]. i’ve made progress and i created a few new concepts which might help you and probably saves a lot of your time.
it is important not to mix the two different Qt concepts: ‘Qt way of ModelViewController’, so let’s revisit the docs:
IMPORTANT: both concepts (1) and (2) can’t be combined directly - normally (out of the box). what i’m doing here is actually combining them. as you will see, this can be quite complicated.
the first blog posting refers to the automate project, the second to the ‘spring random map generator’. this posting is mainly about the ‘spring random map generator’. currently the automate codebase is deprecated and broken. i will eventually fix it. this is how the ‘spring random map generator’ looks like:
so let’s have a detailed discussion about every of those points.
since most of the code given by the QAbstractItemView wasn’t used anyway i removed it (refactoring). now the GraphicsScene is the new view and functionality is added using direct signal&slot connections.
that is basically all you need to do, if you want to use your QGraphicsScene as a View on top of a QAbstractItemModel. it’s better to have less code to care about!
my first implementation of adding nodes and connections between them was very limited. see [4], the automate project. as a arrow in the diagramscene [5] i needed both other QGraphicsItems first in order to know the source and the destination coordinates to draw a line.
not doing so would crash the program as the draw routine of the QGraphicsView, when drawing a connection, would query a QGraphicsItem’s position (the node) which was simply not there anymore. note: this has a cyclic dependency:
QVariant SceneItem_Node::itemChange ( GraphicsItemChange change, const QVariant &value ) {
to sum up: to reduce code and complexity it is important to make insertion and deletion in arbitrary order, see (3) how i did it.
since problem (2) only requires the position of an object i decided to implement a messenger class:
the concept might look quite complex but it works great as one can remove connections or modules (ports) in arbitrary order, just what i discussed in (2).
in the last posting [2] i wondered how to implement properties without adding yet another hierarchy layer. it seems it can be done by doing so. see the image in this posting: it features two different views using the same QAbstractItemModel.
again, what was the problem?
the problem was with the hierarchy layer:
which was extended by:
as there are two different views:
that means we have to take care for the third layer as there can be a port or a property.
the QGraphicsScene/QGraphicsView ignores properties. as it simply ignores them. the QTreeView would render ports but to avoid that one can use a QFilterProxyModel which filters out all ports (and all childs of them). this way only modules and properties are there.
i always wanted to use graphiviz to layout my automate. i’ve found a implementation at [7] which describes how to do so. i did not find the time yet to use that code. maybe i find the time in the future.