set background color to a cell of a tableView
Page |
1 |
I have a tableview that is using a QSqlRelationalTableModel. The table view has a column that I want to color the cell (or row) with the highest sales total (column 5). I can iterate through the model and get the row that the highest value is in. I have tried several methods to color the cell to no avail. I have read that it can be done with a custom proxy or delegate but no samples of code so I am not sure what they mean. From what I have read, the following should work.
- printModel-> setTable (mTableName);
- printModel->select();
- QModelIndex modelIdx = model->index(rowHighSales, 5, QModelIndex()); //rowHighSales is the row with the highest sales
- model->setData(modelIdx, yellow, Qt::BackgroundRole); //this returns false if I use debug. red is a QBrush
Can this work or is there a better way to do it?
Thanks
53 replies
I’m not sure. You would need to look at the source for QSqlRelationalTableModel::setData() to see how it handles the background role – I suspect it doesn’t support it.
If that is the case a simple approach would be to use a very simple proxy model that returns the correct background color in the data() function.
Yes, indeed, a proxy model is the way to go.
What you do is that you subclass QSortFilterProxyModel, and reimplement the data() method to return the source data for the DisplayRole and the EditRole, and returns your color for the BackgroundRole when asked for it.
I have written a generic proxy model that basically just overlays an existing table-type model (that is: it doesn’t work on trees, only on a specific level of one). The overlay model supplies one set of roles, while the underlying model supplies the rest. You can use setData() on it to set data on all roles, and it will either store the value in the overlay model or forward the call to the source model. You can also use it to adjust flags. You could use a setup like that to set your color like you do now, but store it in your own “overlay model” instead of in the QSqlRelationalTableModel. It is not very hard to implement.
You could start reading the docs [doc.qt.nokia.com] , they are really good.
Ok so I re read the docs, and searched, but couldn’t get it to work. Here is what I have….where did I go wrong? In setting up the table I use
- QAbstractItemModel myModel;
- printModel->setSourceModel(myModel);
- ui->printView->setModel(printModel);
and I get an error: cannot declare variable ‘myModel’ to be of abstract type ‘QAbstractItemModel’ because the following virtual functions are pure within ‘QAbstractItemModel’: virtual QModelIndex QAbstractItemModel::index(int, int, const QModelIndex&) const .(and many more)
I think I have to add something else…how and what do I need to do? I copied the code almost exactly.
It tells you what is wrong, QAbstractItemModel is not creatable. It is the abstract base class of all Models, and it is ABSTRACT. you normally go this way:
- printModel-> setTable (mTableName);
- printModel->select();
- MyQSFPM* proxy = new MyQSFPM(this);
- proxy->setSourceModel(printModel);
- ui->printView->setModel(proxy);
now you have to create MyQSFPM as derived class of QSortFilterProxyModel abd reimplement data.
- {
- ...
- }
I feel stupid. I have read several docs and searched and still do not understand how to reimplement the data in the derived class. Do I simply copy the implementation of the functions I need to use and put them in the derived class? I am going to continue reading and trying things. Sorry for not understanding.
Hi poporacer.
Overwriting methods is standard C++ knowledge.
For more information about model / view, look here:
Qt documentation – Model/View Programming [doc.qt.nokia.com]
I feel stupid. I have read several docs and searched and still do not understand how to reimplement the data in the derived class. Do I simply copy the implementation of the functions I need to use and put them in the derived class? I am going to continue reading and trying things. Sorry for not understanding.
As Gerolf points out, overriding virtual methods is a key feature of object oriented programming in C++. It is an essential part of subclassing.
What you need to do in this case, is to handle the cases you want to handle in your reimplementation of data() in your subclass, and use the base implementation for all other cases. Note that it is often a good idea to call the base class implementation of an overridden method in the reimplementation.
In your case, your data method might look something like this*:
- {
- if (!index.isValid())
- } else {
- }
- } else {
- return sourceIndex.data( role );
- }
- }
Perhaps that can help you get started.
*) That means: typed in the forum editor, don’t expect this to compile or be complete
Edit: changed sample to return a color, not a checkbox state. I was confused with another question
In your case, your data method might look something like this*:
I think you got two threads mixed up, this one is about the background role ;-)
So in this case you reimplementation may look something like:
- {
- if (!index.isValid())
- } else {
- }
- }
where m_maxRow is a member variable that you need to set.
In your case, your data method might look something like this*:I think you got two threads mixed up, this one is about the background role ;-)
Yeah, that’s what I just realized. There is another running question on putting checkboxes from an SQL model in a QTableView, and I confused the two. I was already editing my response.
I have read the code, read the docs you suggested and yet have not been able to get it to work. I am not sure if I am reading too much into this. So let me explain what I understand that I shoul do so far. I need to create a new class (MyProxyModel) and inherit QSortFilterProxyModel. Then in my class reimplement the data function ( I think that in ZapB’s code the declaration
should go at the top of the function?) I am not sure what is meant by having to set m_maxRow is this to the total number of rows or the row number that I want to set the background color? Then in my main class I set up the table following Gerolf’s suggestion. Here is what I have:
myproxymodel.h
- #ifndef MYPROXYMODEL_H
- #define MYPROXYMODEL_H
- #include <QSortFilterProxyModel>
- {
- Q_OBJECT
- public:
- MyProxyModel();
- ~MyProxyModel();
- };
- #endif //MYPROXYMODEL_H
myproxymmodel.cpp:
- #include "myproxymodel.h"
- {
- }
- {
- if (!index.isValid())
- {
- }
- else
- {
- }
- }
- #include "myproxymodel.h"
- .
- .
- .
- {
- printModel-> setTable (mTableName);
- printModel->select();
- MyProxyModel* proxy = new MyProxyModel(this);
- proxy->setSourceModel(printModel);
- ui->printView->setModel(proxy);
I get several compile errors and I have tried to figure out why, but can’t figure it out.
Line 12 in the main class gives me the error
no matching function for call to ‘MyProxyModel::MyProxyModel(MainClass* const)
Line 14 in the main class gives me the error
‘QAbstractItemModel’ is an inaccessible base of ‘MyProxyModel’
Am I going about this correctly? I am trying to figure it out on my own by “reading the docs” but the docs I have trouble understanding. Where am I going wrong?
In reading, I see this function:
bool QAbstractItemModel::setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ) [virtual] Is this of any use?
You must log in to post a reply. Not a member yet? Register here!



