add read-only diff column to QSortFilterProxyModel that calculates on model data
Page |
1 |
I’m trying to use an instance of QSortFilterProxyModel to add a read-only column that takes a difference of two columns existing in the source model.
The code that I am using to add the column attempt to alter the its value:
- balanceProxyModel->insertColumns(6, 1);
- for (int i = 0; i < balanceProxyModel->rowCount(); ++i) {
- float budget = balanceProxyModel->index(i, 4).data().toFloat();
- float actual = balanceProxyModel->index(i, 5).data().toFloat();
- float difference = budget - actual;
- qDebug() << ATLINE << ":" << "diff not added!!!";
- }
- ...
- }
Unfortunately in the above example, it streams “diff not added!!!” for every iteration. The diff column shows up, but it is empty.
I have asked at StackOverflow.com [stackoverflow.com] but the only thing we could find is that the flags for that index are not set to Qt::ItemIsEditable.
The only thing is, I don’t want it to be editable by the user, I just want to edit it programatically.
It has been suggested that I should subclass QSortFilterProxyModel and set the column there. I know how to subclass Qt class, minimally (that is without changes), but not how to reimplement setData to allow an update.
Thanks.
24 replies
The Qt::ItemIsEditable is unset. What I meant was I don’t think my problem stems from the fact that the Qt::ItemIsEditable is unset for that index.
My source model is QSqlTableModel. It is attached to a SQLite database. The diff column that I wish to create will be a difference between to fields on that table. I see it as redundant data to have a difference field in my database table since it can (maybe) be readily created by the interface. Also, if I did create the field in the database table, I would have to have the view refresh after every change to the model (and I don’t know how to do that yet.)
The main issue, though, is when I try to setData on the proxy model, I get false. How should I set the column values on the proxy model?
Thanks.
Since it was suggested prior to posting here, I set the Qt::ItemIsEditable flag via instancing the following class instead of QSortFilterProxyModel:
- #include <QSortFilterProxyModel>
- Q_OBJECT
- public:
- }
- return itemFlags;
- }
- };
However, this did not affect the return results from the calls to setData(). It still returns false.
Well, ok.
Since QSortFilterProxyModel just usually forwards the calls to the SourceModel, I think you will have to handle it yourself in your custom proxy model. What I would do is to reimplement the following methods in my ProxyModel :
- flags() for the additional column ;
- columnCount() to “add” your column ;
- data() to retrieve the additionnal data ;
- headerData()
Let’s give it a try :
- Q_OBJECT
- static const int DifferenceColumn = 6;
- public:
- }
- {
- }
- {
- if (index.column() == DifferenceColumn)
- {
- }
- }
- {
- {
- Q_ASSERT(model);
- const int firstColumnIndex = model->fieldIndex("MyFirstColumn");
- const int secondColumnIndex = model->fieldIndex("MySecondColumn");
- const int difference = data1.toInt() - data2.toInt();
- return difference;
- }
- }
- {
- {
- return tr("Difference");
- }
- }
- };
However, I didn’t try it, so you might have to adjust it.
Wow, thanks for all of the effort, octal! I’m still sketchy on subclassing Qt classes as far as what works and what to pass forward.
I tried the above, but didn’t see any difference in the Diff column (its still blank.) I tried commenting out the insertColumns line, but that only removed the column from the view.
Also, the Diff column has no header displayed, which is weird since I entered your headerData function above.
Another weird thing is that I am counting the number of fields and when I include the insertColumns and your code for the subclass, it actually shows 8 columns numbered (0 – 7.)
Is this a common task to ask of the Qt (adding a meta-field that isn’t really in the source table?)
Thanks again.
Damn, I forgot one important thing : the index.
Because of that, I think it would actually be better to directly subclass QSqlTableModel. I’m a little bit tired, so I’ll let you with this code sample :
- static const int DifferenceColumn = 2;
- Q_OBJECT
- public:
- setTable("datas");
- select();
- }
- {
- return count + 1;
- }
- {
- if (index.column() == DifferenceColumn)
- {
- }
- }
- {
- {
- const int firstColumnIndex = fieldIndex("data1");
- const int secondColumnIndex = fieldIndex("data2");
- const int difference = data1.toInt() - data2.toInt();
- return difference;
- }
- }
- {
- {
- return tr("Difference");
- }
- }
- };
- {
- db.setDatabaseName(":memory:");
- db.open();
- QSqlQuery query;
- query.exec("create table datas (data1 int, data2 int)");
- for (int i = 0; i < 10; ++i)
- {
- query.prepare("INSERT INTO datas VALUES (:data1, :data2)");
- query.bindValue(":data1", qrand() % 100);
- query.bindValue(":data2", qrand() % 100);
- query.exec();
- }
- MyCustomModel *model = new MyCustomModel(this);
- view->setModel(model);
- layout->addWidget(view);
- setLayout(layout);
- }
When I was subclassing QSortFilterProxyModel, all the indexes refering to the additional column we created were invalid.
@Andre, thanks for the tip!
I’ve almost gotten it to work using the proxy model.
The weird thing is, that the new column shows and displays the correct field name and value (the difference,) but after I update one of the values in the table the difference column disappears.
Any ideas? It removes the column if I use either QSortFilterProxyModel or my subclass.
Thanks.
No, I didn’t. I have not heard of that before.
I just found it mentioned here [developer.qt.nokia.com], though:
I’ll give that a shot and see what happens.
Thanks!
Hmm. Do I have to sign up with gitorious to get these files?
I can click in them and copy out the text and create my own files, since there’s not many. For some reason it doesn’t give me the choice to just download them in Opera on Linux. This is the first time I’ve dealt with files on a gitorious (or git) server.
I cut and pasted the modeltest source files, this morning. I’ll get to test with them tonight, hopefully.
Update —20110913_1249—
I just figured out the download thing. I just need to click on the “Raw blob data”. Heh, wish I would have seen this sooner. I’m an idiot.
Also, the link to Model Test [developer.qt.nokia.com] says to include the modeltest.pri file inside of my project’s pro file, but there was no .pri file in the repository. I’m going to assume that means to rename modeltest.pro to modeltest.pri and include that.
You must log in to post a reply. Not a member yet? Register here!



