PDA

View Full Version : QAbstractProxyModel: adding a virtual column



ultim8
28th August 2008, 15:20
What I have:

I have a QSqlTableModel that represents a person.
I then have QDataWidgetMappers set up on QLineEdits to modify that person's information.


What I want:

A single QLabel that displays a concatenation of some of the person's information formatted in a way that is different from the original model. For instance: "John Doe (1 yr, 4 mos; M; 3/31/07)"
When any of the information from the original model is updated, the QLabel should be updated immediately


To achieve this I think subclassing QAbstractProxyModel is the correct thing to do. I want the subclassed proxy model to have one extra column then the source model -- that extra column will be the concatenation of the person's information.

The problem is, I can't figure out how to do this....

so... How do I:

Create a proxymodel that has one extra vitual column?
The rest of the columns are a one to one match of the source models columns
If any of the columns are updated in the source model, they are immediately reflected in the proxy model (including the virtual column)


I know I can connect the source models dataChanged event to a function to manually update the QLabel... but I want to learn how to do it this way (because there are other parts in my program that this could be useful).

I've already looked at the below post, but unfortunatly I'm going to need a little more hand holding then that post provides.
http://www.qtcentre.org/forum/f-qt-programming-2/t-qabstractproxymodel-and-virtual-columns-8070.html/?highlight=QAbstractProxyModel

wysota
28th August 2008, 16:09
You don't need a proxy here. Simply connect to the data widget mapper's currentIndexChanged() signal with a custom slot and set the text of the label there. Also connect the same slot to the dataChanged() (and possibly modelReset()) signal of the model.

ultim8
28th August 2008, 17:07
You're right. For this specific instance I don't *need* a proxy. But I want to figure out how to do it with a proxy anyway.

The reason why is there are other places in my program that would greatly benefit from a proxy model that had a virtual extra column. For instance I have a QTableView that displays data for a QSqlTableModel. In the view, I wish for an extra column that does a summation of the values of a few other columns. A proxy model would be ideal for this instance.... unless there is a better idea that I'm not thinking of.

wysota
28th August 2008, 17:23
If you insist on using a proxy then adding a column to a model is very simple. You need to return a larger columnCount() than for the original model. Furthermore you need to modify the mapToSource() method to account for the additional column (it should return an invalid index for the additional column). Furthermore you need to reimplament data() to return data for the column.

ultim8
28th August 2008, 17:42
Right... but a widget mapped to that virtual column does not get updated when when the columns that the virtual column consists of gets updated.

There needs to be some kind of signal for the model to mention that the virtual column has changed whenever any of the columns associated to the virtual column changes... And thats where I'm stuck...

wysota
28th August 2008, 17:47
You need to reimplement setData() and emit a dataChanged() signal for the artificial index whenever any of its dependencies get updated. Alternatively simply monitor for dataChanged() signal from the source model and if any of the changed indices affect the artificial column, emit dataChanged() for it.

ultim8
28th August 2008, 18:10
oh... that makes complete sense. I didn't realize that the dataChanged signal would trigger a call to update a widget mapped to the model... but now that I think about it... of coarse it would.

Thanks for your help.