PDA

View Full Version : Custom QAbstractProxyModel



alizadeh91
3rd December 2012, 15:04
Hello
I have a question about QAbstractProxyModel. Suppose there is model and view.
I want to use a proxy between model and view which multiplies a column of data in model by a value. Is it possible?
Thanks

wysota
3rd December 2012, 15:07
Yes, of course.

alizadeh91
3rd December 2012, 15:09
Should i re-implement specific methods for that?

wysota
3rd December 2012, 15:45
Should i re-implement specific methods for that?

Yes, you need to implement all pure virtual methods and reimplement those virtual methods that govern the behaviour you want to change. Note that if you're not used to proxy models and you only wish to change data returned by the base model, consider subclassing QSortFilterProxyModel instead of QAbstractProxyModel.

alizadeh91
3rd December 2012, 15:54
Thanks for useful hints,
That's true, i can use QSortFilterProxyModel. But in this case what methods should i re-implement?

wysota
3rd December 2012, 19:09
But in this case what methods should i re-implement?
If you wish to modify values returned by the model, reimplement data().

anda_skoa
4th December 2012, 19:56
Since you don't want to change the structure of the data, I'd suggest to have a look at QIdentityProxyModel.

So you'll only have to reimplement data and can forward any call that is not the display role and for the column which you want to change.

Cheers,
_

alizadeh91
6th December 2012, 23:07
Here is what i want to do, see if can suggest me best way:
I have a view and a custom header with comboBox for every column.
In the comboBox there are some units(e.g kilogram,gram, pound, ...). if user change the unit, the content of that column have to be changed according to unit.
Since just the unit of data is changed i don't want to change the model. I just want to display its equivalent in desired unit.
So i thought best way to implement this is proxy. may be if i use a proxy in model i can fix the model but just change the displaying data in proxy.
Is that true?
Is there better solutions?

wysota
6th December 2012, 23:39
So i thought best way to implement this is proxy. may be if i use a proxy in model i can fix the model but just change the displaying data in proxy.
Is that true?
Is there better solutions?

Hmmm... are you even reading what we have been writing here? Posts #6 and #7 already contain all the answers you need.

alizadeh91
7th December 2012, 07:57
Thanks wysota, Yes i'm reading! i just want to clear the problem!

alizadeh91
15th December 2012, 08:52
If you wish to modify values returned by the model, reimplement data().
Thanks again wysota, I've implemented the data() and it's ok except that the table doesn't update itself when i modify values returned by the model. I've even
try emit dataChanged() signal but i'm getting a weird error:


error: C2662: 'QAbstractItemModel::dataChanged' : cannot convert 'this' pointer from 'const TCustomProxyModel' to 'QAbstractItemModel &'
Conversion loses qualifiers


(TCustomProxyModel: my custom proxy model)

Just another thing: when i click on table the table update itself!!!

wysota
15th December 2012, 10:21
You can't emit dataChanged() from data() which is a const method. Invalidate the proxy model when its data changes (that is when you perform action that will cause the proxy to return different values).

alizadeh91
15th December 2012, 10:37
Invalidate is a little slow wysota!!! :(

Sorry: that was my fault because i put invalidate in data() method which cuased a infinite loop!!!

alizadeh91
25th December 2012, 12:00
Hi wysota:
I've implemented it with QSortFilterProxyModel and reimplemented the data() method and it works fine :). Thanks.
But there is another thing: I want to modify and even change the values which return to model when user edit in view. For example suppose i have a model and this model is shown in a view. when user want to modify a value in view, the value before get to model have to pass a filter in proxy model. How can i do that? Do i have to reimplement setData() ? if so, how?
Thanks.

Do i have to do this with delegate? I mean modify data returned to model in setModelData() method? I'll prefer to do this in proxy model! if is possible?!

wysota
25th December 2012, 13:19
The filter doesn't influence editing the data. If you want, you can reimplement setEditorData() and setModelData() of the delegate.

alizadeh91
5th January 2013, 20:51
But wysota i have implemented it in this way in proxy model: this->sourceModel->setData(..); Is this way is a right way?! any way it works perfect!

wysota
6th January 2013, 00:52
But wysota i have implemented it in this way in proxy model: this->sourceModel->setData(..); Is this way is a right way?! any way it works perfect!

I meant that this is the default implementation of setData() in a proxy.