View Full Version : TableView and setting background color of a cell that was not modified

20th September 2012, 23:54
I have a custom table view, with custom model, and custom cell delegate.
I need the ability to change the background color of a cell depending on the contents of another cell.
For example if I modify cell (2,2) I may need to change the background color of cell(5,3).

I originally set it up so it would set the background during the cell delegate's paint routine. the problem is when I modify cell (2,2) the paint routine is never getting called for cell (5,3). I can call repaint() on the entire table but I would prefer not to do this.

I run into a similar issue if I try to set the background using the model. Another issue with the model is that the background role issued for the model is done after the cell delegate's paint routine which prevents me from using the cell delegate's paint routine to draw other things within the cell.

Is there an easy way to do this? If so how should I proceed?

21st September 2012, 08:58
Use Qt::BackgroundRole of the model to set the color.

21st September 2012, 17:26
Use Qt::BackgroundRole of the model to set the color.

That won't solve my issue as now I can not style the cell since the Model paints the background color after the cell delegate paint event.
For example I may want a wavy line to appear under the text in the cell.
So what happens is the cell delegate paints the wavy line and then the model paints the background which cover's the wavy line.

If there is a way to paint the wavy line using the model and not use the cell delegate?

21st September 2012, 23:36
If some cell data has been changed and you need another cell's contents to be updated in turn you should do that via the model, something like this:

bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
int row = index.row();
int col = index.column();

if(role == Qt::EditRole && col == SOME_SPECIAL_COLUMN)
// do editing

// update entire row
QModelIndex left = index(row, 0);
QModelIndex right = index(row, columnCount() - 1);

emit dataChanged(left, right);

return true;

return false;

Inside your custom delegate's paint method you can paint the background like this

void CustomDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
// figure out how the cell should be drawn
// ...

QColor background = index.model()->data(index, Qt::BackgroundRole).value<QColor>();
painter->fillRect(option.rect, background);

A delegate is usually responsible for drawing a cell's contents. So if you provide a custom delegate there should be no class "overpainting" that cell or its background. If I still miss your point you need to provide some code.

22nd September 2012, 01:57
That won't solve my issue as now I can not style the cell since the Model paints the background color after the cell delegate paint event.
The model doesn't paint anything. Only the delegate does. You have complete control over what the delegate does.

23rd September 2012, 21:20
Ok I got it now.
I did not realize that the model invokes the delegate's paint event.
I also had my delegate do my custom styling and then I called the base QStyledItemDelegate::paint() which was just painting over the stuff I just painted.
All is working, Thanks for your help.

28th September 2012, 00:44
I am still having some issues. I need to change the color of some cells when I change a row. I call model->data(index, Qt::BackgroundColorRole); on an index located in the previous row but paint is not being called. Is there someway I can invoke the paint() for that cell? I do not want to emit datachanged() because the data did not change only the background color.

Note that the cells changes to the correct color if I cover the widget up with another window and uncover it as this will invoke the paint routine.

Added after 33 minutes:

yay I think I found a solution. I ended up calling tableview->update() and passing it an index from the proxy model.