Saturday 29 December 2012

Not so QStandardItem...

So there I was trying to work out how I might integrate a model/view design into QtMax for handling all of the list/tree widgets, and I got to reading the QStandardItem/Model documentation.

"Hey, that sounds like just the thing I need!" I thought to myself, and hacked away at creating the wrapper code for QStandardItem and QStandardItemModel, using a custom QStandardItem object which handled user Object data on-the-fly.

Everything was looking shiny and new, so I decided I should test it out, and knocked together a quick QComboBox test app, which used my model and added a couple of items via the comboBox API.

Ta da! … oh, wait… nothing is actually happening!?

Further investigations revealed that QComboBox wasn't designed to expect a subclassed QStandardItem and went happily off to create base QStandardItems itself without using the "factory" that the documentation said I should implement (::clone()).

Which, as one would imagine, was somewhat of a let down after writing a whole bunch of code that I couldn't use ;-)

… time passes …

I pondered and pondered for a while, and went through a couple of mis-starts, but then came upon the idea that the best thing to do would be to code most of what I needed in BlitzMax, and interface that directly with the backend C++ classes, which would mostly act as a pass-through.

Okay, so the thought of implementing my own item/model for plugging into a QAbstractItemModel was a tad on the daunting side, considering that I wasn't only writing a couple of C++ classes, but a bunch of helper types, object transformations  and the main BlitzMax types to hold everything together.

I ended up keeping the names, QStandardItem and QStandardItemModel, and rewrote what I already had. I decided that all the item info needed to be kept in the Type, so I came up with a way to store everything in a TMap based on the "roles" that the model/view framework uses. I also built a custom children item holder which is based on an array, rather than a TList. I thought that it would be quicker doing lookups on an array index than trawling through a TList, and I am happy to take a hit on the resize of the array when it is required.

Because the underlying system passes data via QVariant, we need to do a lot of conversion between that and Objects. but it's simple casting so it shouldn't be too slow.

It took a whole day to get to a point where I was ready to try the QComboBox test app again, and after a couple of minor tweaks, I was very pleased with the results.
A simple call to :


combo.addItem("item 1", data)


iterates through the entire model framework, creating a new QStandardItem and populating it appropriately with all the role data, and even the user "data" object, which you can then retrieve by calling itemData(index) !

Of course, there's still much to do, like implementing cleanup and so forth, but with the basic engine running I feel much better about using this as a core for all of the Item-based widgets - lists and trees.

:o)

No comments:

Post a Comment