In QTableWidget changing text color of selected row

I am using QTableWidget to display multiple rows. Some of these lines should reflect the error and the text color changes:

Lines indicating no error are displayed in the default color (black text on white on my computer).
The lines reflecting the error are displayed with red text color (this is red text on a white background on my computer).

It's okay as long as there is no choice. As soon as a row is selected, regardless of the color of the unselected text, the text color turns white (on my computer) on a blue background.

This is what I would like to change to get this:
When the row is selected, if the row reflects, there is no error, I would like it to appear with white text on a blue background (default behavior).
If the line reflects an error and is selected, I would like it to appear in red text on a blue background.

So far I've managed to change the highlight color for the entire QTableWidget, which is not what I want!

+5


source to share


5 answers


Answering the question, here's what I did: delegate.

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

I'm not sure if this is very reliable, but at least it works great 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's how to use it:

QTableWidget* pTable = new QTableWidget(...);
pTable->setItemDelegate(new MyItemDelegate(this));

      

+8


source


It looks ok, but you can look at the documentation QStyleOption

, it can tell you that the selected item is selected or not, you don't need to look at the draw's color to do this. I would probably give the model class a user role that returns whether the data is valid or not and then makes a color decision based on that. That is, it rIndex.data(ValidRole)

will return if the data for this index is valid or not.



I don't know if you tried to override the data for BackgroundRole and return a custom color, Qt might do the right thing if you change the color there

+1


source


What you need to do is selectionChanged()

wire the signal emitted by the QTableWidget QItemSelectionModel to a slot, say OnTableSelectionChanged()

. In a slot, you can use QStyleSheets to set the selection colors like this:

if (noError)
{
    pTable->setStyleSheet("QTableView {selection-background-color: #000000; selection-color: #FFFFFF;}");
}
else
{
    pTable->setStyleSheet("QTableView {selection-background-color: #FF0000; selection-color: #0000FF;}");
}

      

+1


source


You can of course inherit from the table widget and override the paint event, but I don't think that's what you want to do.

Use functionality instead QAbstractItemDelegate

. You can either create it to always be used for error lines and set error lines to use this delegate, or create a generic one that knows how to draw both types of lines. The second method is what I would recommend. Then your delegate draws the rows accordingly, even for the selected row.

0


source


You can use for example. a proxy model for this, where you return a different color if you have an error for a specific modelindex;

    QVariant MySortFilterProxyModel::data(const QModelIndex & index, int role = Qt::DisplayRole) {
       // assuming error state and modelindex row match
       if (role==Qt::BackgroundRole)
         return Qt::red;
   }

      

0


source







All Articles