C++ QHeaderView样式每个列

C++ QHeaderView样式每个列,c++,qt,stylesheet,qheaderview,C++,Qt,Stylesheet,Qheaderview,我正在尝试编辑QTreeWidget的标题样式 我发现我可以用QHeaderView::section编辑它,然后在那里编辑背景、颜色、边框 但是,我想单独编辑列标题。我在上发现我们可以使用::first,::last 是否有任何方法可以精确地指定另一个节(例如使用类似[index=3])。否,除了使用::first,::last,::middle之外,没有其他方法可以使用样式表更改标题节的外观。QStylesheetStyle(加载样式表时使用的样式)仅实现这些状态 要解决这个问题,基本上可以

我正在尝试编辑
QTreeWidget
的标题样式

我发现我可以用
QHeaderView::section
编辑它,然后在那里编辑背景、颜色、边框

但是,我想单独编辑列标题。我在上发现我们可以使用
::first
::last


是否有任何方法可以精确地指定另一个节(例如使用类似
[index=3]
)。

否,除了使用
::first
::last
::middle
之外,没有其他方法可以使用样式表更改标题节的外观。
QStylesheetStyle
(加载样式表时使用的样式)仅实现这些状态

要解决这个问题,基本上可以使用一个自定义的
QHeaderView
,它重新实现了它的
paintEvent
,或者我建议您的选项:使用自定义样式(a是一个好选项,因为它只允许您实现所需的功能,并从基本样式继承其余的功能)。您必须专门为
CE_头
元素重新实现
drawControl
方法:

virtual void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override {
  if (element == CE_Header) { // sections
    // ...
  } else { // default behaviour for anything else
    QProxyStyle::drawControl(element, option, painter, widget);
  }
}
现在,
QStyleOptionHeader::section
变量包含正在绘制的部分的索引,因此您可以使用它来计算颜色

最低代理样式的完整代码为:

class MyProxyStyle : public QProxyStyle {
public:
  MyProxyStyle(const QString& name) : // "fusion", "windows", ...
    QProxyStyle(name) {
  }

  virtual void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override {
    if (element == CE_Header) {
      auto ho = *qstyleoption_cast<const QStyleOptionHeader*>(option);
      auto headerView = qobject_cast<const QHeaderView*>(widget);
      ho.text = QString::number(ho.section); // for testing, it prints the section index
      auto pal = ho.palette;
      const QColor color(ho.section * 32 + 64, 0, 0); // color based on index
      pal.setBrush(QPalette::All, QPalette::Button, color);
      ho.palette = pal;
      QProxyStyle::drawControl(element, &ho, painter, widget);
    } else {
      QProxyStyle::drawControl(element, option, painter, widget);
    }
  }
};
class MyProxyStyle : public QProxyStyle {
public:
  MyProxyStyle(const QString& name) : // "fusion", "windows", ...
    QProxyStyle(name) {
  }

  virtual void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override {
    if (element == CE_TabBarTab) {
      auto to = *qstyleoption_cast<const QStyleOptionTab*>(option);
      auto tabBar = qobject_cast<const QTabBar*>(widget);
      for (int ii = 0; ii < tabBar->count(); ++ii) { // must find manually the tab
        const auto rect = tabBar->tabRect(ii);
        if (rect.x() == to.rect.x()) { // found the index of tab being painted
          to.text = QString::number(ii); // for testing, it prints the tab index
          auto pal = to.palette;
          const QColor color(ii * 32 + 64, 0, 0); // color based on index
          pal.setBrush(QPalette::All, QPalette::Button, color);
          pal.setBrush(QPalette::All, QPalette::Background, color);
          to.palette = pal;
          break;
        }
      }
      QProxyStyle::drawControl(element, &to, painter, widget);
    } else {
      QProxyStyle::drawControl(element, option, painter, widget);
    }
  }
};
设置画笔时使用不同颜色角色的原因是,不同的样式在绘制部分时使用不同的角色(fusion样式使用
Qpalete::Button
作为背景,而windows使用
Qpalete::background
)。例如,其他角色将允许您调整边框和文本颜色

结果

融合风格:

使用windows样式:


在一些简单的情况下,您可以使用QBStractItemModel和roles的方法更改QHeaderView的部分颜色:

// text of 0-section will be red in header
m_model.setHeaderData(0, Qt::Horizontal, QBrush(Qt::red), Qt::ForegroundRole); 

// background of a 25-section will be blue in header
m_model.setHeaderData(25, Qt::Horizontal, QBrush(Qt::blue), Qt::BackgroundRole);

(“大家好”顺便说一句…似乎我无法编辑文章来添加此…)哎呀,我读了它,不知道为什么会想到
qtabar
。。。让我在一分钟内发布更改更新!对不起,关于混乱的THX:)它远远超出我所知道的,我不知道我是否可以使用它(这是相当大的应用程序使用C++核心和JS引擎的一部分,所以我不太知道如果我可以(允许)重新定义这个……而且我们使用样式表很多,我们仍然在QT 4(移动到5,最后^ ^)。如果我实现了这一点,我会回来的,不过还是要感谢您提供的详细信息!我想我现在将使用::first等等;)