Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a QTableWidget, changing the text color of the selected row

Tags:

qt

I'm using a QTableWidget to display several rows. Some of these rows should reflect an error and their text color is changed :

Rows reflecting that there is no error are displayed with a default color (black text on white background on my computer).
Rows reflecting that there is an error are displayed with a red text color (which is red text on white background on my computer).

This is all fine as long as there is no selection. As soon as a row is selected, no matter of the unselected text color, the text color becomes always white (on my computer) over a blue background.

This is something I would like to change to get the following :
When a row is selected, if the row is reflecting there is no error, I would like it to be displayed with white text on blue background (default behavior).
If the row is reflecting an error and is selected, I would like it to be displayed with red text on blue background.

So far I have only been able to change the selection color for the whole QTableWidget, which is not what I want !

like image 566
Jérôme Avatar asked Nov 13 '08 08:11

Jérôme


2 Answers

Answering myself, here is what I ended up doing : a delegate.

This delegate will check the foreground color role of the item. If this foreground color is not the default WindowText color of the palette, that means a specific color is set and this specific color is used for the highlighted text color.

I'm not sure if this is very robust, but at least it is working fine on Windows.

class MyItemDelegate: public QItemDelegate
{
public:
  MyItemDelegate(QObject* pParent = 0) : QItemDelegate(pParent)
  {
  }

  void paint(QPainter* pPainter, const QStyleOptionViewItem& rOption, const QModelIndex& rIndex) const  
  {
    QStyleOptionViewItem ViewOption(rOption);

    QColor ItemForegroundColor = rIndex.data(Qt::ForegroundRole).value<QColor>();
    if (ItemForegroundColor.isValid())
    {
      if (ItemForegroundColor != rOption.palette.color(QPalette::WindowText))
      {
        ViewOption.palette.setColor(QPalette::HighlightedText, ItemForegroundColor);
      }
    }
    QItemDelegate::paint(pPainter, ViewOption, rIndex);
 }
};

Here is how to use it :

QTableWidget* pTable = new QTableWidget(...);
pTable->setItemDelegate(new MyItemDelegate(this));
like image 92
Jérôme Avatar answered Sep 28 '22 02:09

Jérôme


What you'll want to do is connect the selectionChanged() signal emitted by the QTableWidget's QItemSelectionModel to a slot, say OnTableSelectionChanged(). In your slot, you could then use QStyleSheets to set the selection colours as follows:

if (noError)
{
    pTable->setStyleSheet("QTableView {selection-background-color: #000000; selection-color: #FFFFFF;}");
}
else
{
    pTable->setStyleSheet("QTableView {selection-background-color: #FF0000; selection-color: #0000FF;}");
}
like image 23
Krsna Avatar answered Sep 28 '22 00:09

Krsna