PDA

View Full Version : View using multiple models



johnmauer
15th January 2010, 17:40
I'm trying to build a plot (view) of two or more sets of data, and therefore have two or more models into that data. The resultant view needs to be synced with these multiple models. Is there a reasonable way to merge models that has already been used?

wysota
15th January 2010, 21:53
A proxy model, that's for sure... But how do these models relate to each other? You want to merge them horizontally or vertically?

johnmauer
15th January 2010, 22:37
Horizontally. I have a set of data points (typically 10, to 1oooo points) and fitted analytical curve(s) that need to be overlaid for comparison. I have set up the obvious: a PointsModel to handle the data which populates a QTableView. Now I need to build a plot in a separate view that plots the histogram of the data (using a (vertical) proxy model to calculate the bins) and overlays one or more possible fits. I can represent a fit with an appropriate model, but I don't know how to merge it (them) with the proxy model, especially because the multiple fit models will be signaled from a QListWidget selection(s). Thanks for any help.

wysota
15th January 2010, 22:50
Implement a proxy that will work on two models - the supported sourceModel() and another model. Reimplement index() and data() (and possibly other methods) to take both models into consideration instead of just the sourceModel().

johnmauer
15th January 2010, 23:40
I have been working in that direction. However, data() takes Qt::DisplayRole to return the appropriate data. If I implement multiple responses, I need to use Qt::UserRoles(s) which got a bit cumbersome. I really need to subclass QAbstractItemModel to have a new call to extendedData() with a model identifier (and possibly type)r, and then calls to the separate models thru data(). This seems appropriate, but I was looking for gotchas, things I didn't know about with that kind of subclass.

wysota
16th January 2010, 00:54
I have been working in that direction. However, data() takes Qt::DisplayRole to return the appropriate data. If I implement multiple responses, I need to use Qt::UserRoles(s) which got a bit cumbersome.
Hmm... either I don't understand your problem or you are wrong :)

Do you want a join of two models (2 columns + 2 columns = 4 columns) or an overlay of one over the other (2 columns + 2 columns = 2 columns)?

johnmauer
16th January 2010, 14:44
Ah, I didn't describe it very well. I need to overlay two sets of data from different sources. I already have one set of data, a column of doubles, in a QTableView using a subclass of QAbstractTableModel. I have a proxy model of that data to force a calculation of the data bins for a histogram plot. I now need to overlay a mathematical curve on top of the histogram, but the user can change the parameters for that curve. I subclassed a model from QAbstractItemModel to generate a lookup table from that curve and now need to merge it with the proxy model from the data in order to do the overlay.

I can see several possible ways to do this: use Qt::UserRole types to ask for the different models from data() OR hardcode the QModelIndexes to represent specific model responses OR override all the interface methods from the view to separate the models OR .. The top level proxy model needs to identify the underlying model in some way. However, I thought that Qt might have a standard way to merge models which was my reason for the question.

Sorry for the lack of detailed understanding. I've used another framework (MFC) for awhile. I would include a link to an example plot, but I didn't think that was appropriate. Thanks for your help.

wysota
16th January 2010, 15:10
But why do you need access to both models from outside the proxy model? If those are two separate models then don't try to merge them. Are you using a custom view or a default one? Could you craft an example or a mockup screenshot of what you want to achieve?

johnmauer
16th January 2010, 18:04
I am building a custom view to duplicate the attached graphic. The user can change the data used for the histogram, and the parameters of the curve in other views, so the views need to be synced. I had hoped to subclass the QAbstractItemView class to take advantage of the automatic notification, but that appears to need the notifications to be funneled through one model. If I built my own view, but kept the models, then I would need to implement the same connections. And I am unsure of all the connections between the model and the view.

Please note that, although I have simplified this graphic to just one mathematical curve, the plot could have a dozen such curves. And all of them can be updated by the users elsewhere.

wysota
16th January 2010, 18:14
Ok, you have basically two choices. Either implement a proxy model where you use custom roles (Qt::UserRole and up) to return data from the "second" model or make a proxy where your curves will become additional columns in the proxy model (compared to the source model). From what I see you main model has only one column, so curves can occupy subsequent ones.

One way or the other you will end up with a single model where two source models are represented either by different roles or by different columns.

johnmauer
16th January 2010, 19:06
The approach using different columns is excellent; I had forgotten about the extra column parameter. Thanks a lot.

QtQuery
30th August 2010, 06:19
Good day. Could you tell me how to add extra columns to the proxy model, mentioned above? I tried insertColumn() in my QSortFilterProxyModel subclass but it didn't work (returned false).
Or is it a matter of overriding columnCount() and data() to return the data from the second model in a new column?
Thanks in advance.

wysota
30th August 2010, 08:52
Or is it a matter of overriding columnCount() and data() to return the data from the second model in a new column?
Yes, that's correct - you need to reimplement at least columnCount(), index(), parent() and data() to take extra columns into account.

NoRulez
5th October 2010, 19:28
Hello,

i've the same problem, i need to merge 2 tree models into one treeview.
The first model is a simple QStandardItemModel. The second model is a QDirModel.
Now i want to display both models into one treeview. So from the posting i think i need an overlay...



CustomModel Items
Custom Item 1 (QStandardItemModel)
Custom SubItem 1 (QStandardItemModel)
Custom SubItem 2 (QStandardItemModel)
Custom Item 2 (QStandardItemModel)
Custom SubItem 1 (QStandardItemModel)
Custom SubItem 2 (QStandardItemModel)
DirModel Items
C: (QDirModel)
Qt (QDirModel)
2010.05 (QDirModel)


So, i think i need two functions setCustomModel(QAbstractItemModel *pModel); and a function setDirModel(QAbstractItemModel *pModel); for example.
But how can i handle it that when i click on an item in the QDirModel to display a file content and if i click on an item in the QStandardItemModel to display for example the a string? To simplify this, i want to know how the treeview knows which model must be accessed.

I've also attached a screenshot of the current situation. In the left (empty) TreeView i will merge the right ones.

Thanks in advance

Best Regards
NoRulez