QTreeModel

Qt has a pretty nice architecture for doing MVC (Model/View/Controller) and being in the Qt Jambi team we wanted make Qt Jambi have access to all this. Unfortunatly we rather quickly ran into 2 big issues:

  • Performance. The Qt itemviews framework is heavily based on the QModelIndex class which is a light-weight object that is allocated on the stack and passed around (primarly) by reference. This means that in C++, allocating these and querying for them is (close to) a no-op. In Qt Jambi these QModelIndices become real Java objects. Java doesn't have the concept of stack allocated objects (though there exists papers on escape analasys, etc, but this is theory and not always applicable), so a QModelIndex suddently becomes a little bit more heavy, pluss it needs to be garbage collected which also costs a little bit.
  • Usability. Hierarchical models are non-trivial. In Qt / C++, we had access to the QModelIndex::internalId() which is a void * which can be used to reference virtually anything in any kind of data model. In Java this maps to a java.lang.Object, but with this also comes the responsibility of memory managment. QModelIndex doesn't reference count, for performance reasons, so by passing the java.lang.Object to the void * would mean that we either leak memory or risk that the object is collected by the garbage collector which will eventually crash. Neither of which are resonable alternatives.... Specially the parent() function becomes tricky to implement in Java.
  • So based on this we sat down and looked at ways to come up with a way to keep the QModelIndices on the C++ side for the performance critical parts and to improve the programming joy that is hierarchical data models. This basically led us QTreeModel, a subclass of QAbstractItemModel, which provides 3 virtual functions:


    public Object child(Object parent, int index)
    public int childCount(Object parent)
    public Object data(Object value, int role)

    As you can see we removed all the QModelIndex from the API, hid the parent() function and introduced the childCount() and child() functions for querying the structure and the data() function for querying the value.

    The data function also has convenience overloads like:


    public String text(Object value)
    public QIcon icon(Object value)

    For querying the most used data roles.

    To interoperate with the rest of the Itemviews framework we also provide mapping functions between QModelIndex and java.lang.Objects which is needed to interact with things like selections, collapsing/expanding, etc.


    public Object indexToValue(QModelIndex index)
    public QModelIndex valueToIndex(Object value)

    I have a little demo app that shows many of the different API aspects here and
    here, such as dynamically adding and changing nodes. Unfortunatly, this stuff is partially based on the in-house version of Jambi so you can't run the first link just yet, but at least it gives you some insight into how easy it is to write tree models in Jambi now. The second link, is shipped as part of the current Qt Jambi beta.

    Who knows... maybe some of this will sneak its way back into Qt / C++ too someday ;-)


    Blog Topics:

    Comments