在QTableWidget中,如何改变选定行的文本颜色?

6
我正在使用QTableWidget来显示多行。其中一些行应该反映出错误,并且它们的文本颜色会发生改变:
反映没有错误的行以默认颜色显示(在我的电脑上是黑色文本在白色背景上)。 反映有错误的行以红色文本颜色显示(在我的电脑上是红色文本在白色背景上)。
只要没有选择,这都很好。一旦选择了一行,无论未选择的文本颜色如何,文本颜色总是变为白色(在我的电脑上),并在蓝色背景上显示。
我想进行以下更改: 当选择一行时,如果该行反映没有错误,则希望以白色文本在蓝色背景上显示(默认行为)。 如果该行反映出错误并被选择,则希望它以红色文本在蓝色背景上显示。
到目前为止,我只能更改整个QTableWidget的选择颜色,这不是我想要的!

你目前用来设置文本颜色的代码是什么样子的? - Parker Coates
6个回答

9

我自己回答一下,这是我最终采用的方法:使用委托。

这个委托将检查项目的前景色角色。如果该前景色不是调色板的默认WindowText颜色,则意味着设置了特定的颜色,并且该特定颜色用于突出显示的文本颜色。

我不确定这是否非常健壮,但至少在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);
 }
};

以下是如何使用它:

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

2
您需要做的是将QTableWidget的QItemSelectionModel发出的selectionChanged()信号连接到一个槽,比如OnTableSelectionChanged()。在您的槽中,您可以使用QStyleSheets来设置选择颜色,方法如下:
if (noError)
{
    pTable->setStyleSheet("QTableView {selection-background-color: #000000; selection-color: #FFFFFF;}");
}
else
{
    pTable->setStyleSheet("QTableView {selection-background-color: #FF0000; selection-color: #0000FF;}");
}

1

看起来还不错,但你可能需要查看QStyleOption的文档,它可以告诉你绘制的项目是否被选中,你不必查看绘制颜色来做到这一点。我可能会给模型类一个用户角色,返回数据是否有效,然后根据此进行颜色决策。即rIndex.data(ValidRole)将返回此索引处的数据是否有效。

我不知道你是否尝试重写BackgroundRole的数据并返回自定义颜色,如果你在那里更改颜色,Qt可能会做正确的事情。


1

我知道这是一个老问题,但我想改进@Jerome的答案:

  1. data(Qt::ForegroundRole)将返回一个非有效的QVariant(因此您不必将其转换为QColor来检查它)。

  2. WindowText调色板颜色并不总是与默认颜色相同,因此在此处检查它并不相关。

  3. 您可以在调整任何内容之前测试当前项目的状态。

我的代码如下:

void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    if (!option & QStyle::State_Selected))
    {
        QStyledItemDelegate::paint(painter, option, index);
        return;
    }

    QStyledOptionViewItem myOption(option);

    auto colorData = index.data(Qt::ForegroundRole);
    if (colorData.isValid())
        myOption.palette.setColor(QPalette::HighlightedText, colorData.value<QColor>());

    QStyledItemDelegate::paint(painter, myOption, index);
}

0

当然,您可以从表格小部件继承并覆盖绘制事件,但我认为这不是您想要做的。

相反,应该使用QAbstractItemDelegate功能。您可以创建一个始终用于错误行的委托,并将错误行设置为使用该委托,或者创建一个通用委托,知道如何绘制两种类型的行。我建议使用第二种方法。然后,您的委托会适当地绘制行,即使是选定的行。


0

你可以使用代理模型,如果针对特定的模型索引存在错误,则返回不同的颜色。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接