Abstract Item Model - violates MVC?
I am currently working on a project that has the next data model:
A set of users having their names and an ID describing them
A set of RFID card, having their ID and type describing them, and also their access level.
The cards can be associated to one of the users for a certain time interval, all associations must be kept for historical look-up.
What I need to do is to present this data to the client in a tree view, on the first level are the users, and on the second one the card which are (or have been) associated to the user. The cards that are currently associated have to be shown in green, the "expired" ones in red.
Now what I do is I store all this data in an SQL database, which is fine, and totally unimportant to you. I subclassed QAbstractItemModel to present the necessary data to the QTreeView.
However what I found is that I actually have to provide the color, what data to show in what column etc. from the model class. I might be wrong - but I see that a violation to the MVC paradigm. I think that the model should be responsible only for looking up the proprer User and Card objects based on the QModelIndex, and leave it up to the View class where to present which datafield.
My opinion is that the data() method of the QAbstractItemModel should return a QObject, which can then be casted to the appropriate type and presented to the user in a way that the View finds appropriate.
Please, share youre thoughts about this.
So you say that model should provide only data. As for color (and other formatting) - it is data too. Sometimes text more relevant, sometimes color, sometimes something else.
About columns. If a model does not know about position of the data how can we fetch it?
If you need to rearrange the data (or change the way it is displayed) the only way to it (at least as i know) is to make subclasses of view and delegate.
The model deliveres the data in a generic way. perhaps there is some data delivered, that is view relevant (text, color) but where to store such things otherwise? Delivering a QObject instead of parent / child / column / row data would mean, the view has to know about the internals of the QObject that you return. How should that one be structured? How would child objects be connected to them?
I think the MVD (Model - View - Delegate) implementation in Qt is very clean and good, with one litte thing, that is color and font role :-)
Returning QObjects from a QAIM would be way too resource intensive, so that is not really an option. You will have to realize that not all models represent data that is stored in that format, or even actually part of the application itself. It may just be showing a small part of a database, or of the file system, or...
Notice however, that you can have your QAIM return a pointer to a QObject of your choice (or any other object) in a role of your choosing. So nothing is stopping you from implementing that. You can also use other roles to signify if a card is associated or not. Just define your own custom role id and go for it! In that case, you can use that role in a custom delegate to determine the rendering characteristics for that case.
You are right that ideally, the model would only supply the actual data, the view would do the layout, and the delegate would do the rendering, but sometimes it is just convenient to be able to take a shortcut. You can also take the middle road, and use a proxy model to attach the formatting data to your data model.
IMHO, the current MVD model in Qt has its flaws, but it is not that bad.