如何更改QTreeView头部的背景颜色?

1 投票
3 回答
6956 浏览
提问于 2025-04-17 01:45

我想改变某些标题部分的背景颜色。有些部分会使用默认颜色,而其他部分则会用不同的颜色。

HeaderView不像QTreeView那样接受委托,它自己负责所有的绘制工作。它通过两个方法来完成这个任务:

我最开始的尝试是重写paintSection方法,让它先绘制默认的内容,然后再添加我自己的内容。

def paintSection(self, painter, rect, logicalindex):
    QHeaderView.paintSection(self, painter, rect, logicalindex)
    painter.save()
    painter.fillRect(rect, QBrush(Qt.red))
    painter.restore()

但是这样似乎没有任何效果。它不会绘制填充的矩形。如果我把调用基类的paintSection方法的那一行注释掉,它会绘制填充的矩形,但效果不太稳定(比如,点击和调整标题的大小时,有时会填充,有时又不会)。

任何帮助都非常感谢。

3 个回答

0

我觉得你不需要重写什么东西。可以看看 palette 这个属性,它是 QWidget 的一个属性。

0

我同意“Harald Scheirich”的观点,样式表确实是个好东西。不过为了让你更信服,我想跟你聊聊样式表中一个不太为人所知的部分,叫做属性选择器。

如果你去看看样式表的文档,这里有一小段关于它们的介绍。简单来说,我们可以为那些具有特定属性的控件指定样式表。比如说,所有的QPushButton按钮如果是扁平的。

QPushButton[flat="true"]
{
   background-color: blue
}

虽然这听起来很酷,但光这样并不能帮到你。更神奇的是,你可以给QObject添加自己的属性。这些叫做动态属性,也可以在属性选择器中使用。

所以我可以创建一个这样的样式表——其中highlightHeader是我自己虚构的属性。

QHeaderView[highlightHeader="true"] 
{ 
   background-color: red
}

现在,你可以把这个样式表应用到每一个QHeaderView上。但因为没有人把highlightHeader设置为true,所以我们不会在任何地方看到红色。因此,下一步是当我们决定要把某个特定的QHeaderView变成红色时,我们就调用这个:

myHeaderView->setProperty("highlightHeader", true);
myHeaderView->style()->unpolish(myHeaderView);
myHeaderView->style()->polish(myHeaderView);

在第一行中,我们设置了一个属性来触发我们想要的状态。接下来的两行是为了确保Qt重新评估这个控件的样式。否则你可能看不到变化。

基本上就是这样。希望这对你有帮助。

2

其实你不需要实现什么,QHeaderView可以通过样式表来修改,就像大多数控件一样。

补充:

你提到想根据数据来改变每一列的背景颜色,最简单的方法可能是从QAbstractItemModel或者其他模型类派生一个新模型,然后重新实现headerData()这个函数。

QVariant QAbstractItemModel::headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const [virtual]

你想要响应的角色是Qt::BackgroundColorRole,所以这个函数可能看起来像这样:

QVariant VariableHeaderModel::headerData(int section Qt::Orientation orientation, int role)
{
  QVariant result;
  if (role == Qt::BackgroundColorRole)
  {
    result = <QColor from custom processing>
  }
  else
  {
    result = Superclass::headerData(section, orientation, role);
  }
  return result;
}

一般来说,在Qt中,模型决定显示什么,通常情况下是改变模型,而不是视图。而且'data()'这个函数会被调用很多次,我不太清楚'headerData()'的情况,但如果有很多计算的话,你可能想要缓存一下结果。

如果你使用的是QStandardItemModel,你可能只需要调用:

setHeaderData(section, orientation, <aColor>, Qt::BackgroundColorRole);

撰写回答