QTableView header 背景色交替

QTableView header background color alternating

使用 Qt 5.7.1 和样式表如何使行 header 部分背景颜色遵循行单元格的相同交替模式 我的样式表是

QTableView {
   alternate-background-color: lightblue;
   background-color: grey;
}

QTableView::item:selected {
   background-color: lightgreen;
}


QTableView QTableCornerButton::section {
   background-color: transparent;
   border: 0px ;
}

QHeaderView {
   background-color: grey;
   alternate-background-color: lightblue;
}

QHeaderView::section {
   background-color: transparent;
   alternate-background-color: lightblue;
}

我尝试通过

启用它
ui->tableWidget3->setAlternatingRowColors(true);
ui->tableWidget3->verticalHeader()->setAlternatingRowColors(true);

不幸的是,它没有用。

您可以不使用 qss 而是使用 QHeaderView 的子类来实现此行为。例如:

#include <QHeaderView>

class AlterHeader : public QHeaderView
{
    Q_OBJECT
public:
    explicit AlterHeader(Qt::Orientation orientation, QWidget *parent = nullptr);

protected:
    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
};

void AlterHeader::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
    Qt::Alignment align = (Qt::AlignHCenter | Qt::AlignVCenter);
    if (logicalIndex % 2 > 0) {
        painter->fillRect(rect, QColor("lightblue"));
    } else {
        painter->fillRect(rect, QColor("grey"));
    }
    painter->drawText(rect, align, QString::number(logicalIndex));
}

并使用:

AlterHeader *header = new AlterHeader(Qt::Vertical, ui->tableWidget);
ui->tableWidget->setVerticalHeader(header);

即便如此,这个话题是6个月前问的,我刚才偶然发现了这个。

Serhiy Kulish 的回答帮了大忙,我想提出两项改进建议(再次覆盖 QHeaderClass,但也可以使用覆盖的 QStyle):

void AlternatingHeaderClass::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const {
    QAbstractItemView* abstractView(qobject_cast<QAbstractItemView*>(parent()));
    if (abstractView && abstractView->alternatingRowColors()) {
        QHeaderView::paintSection(painter, rect, logicalIndex);
        if (visualIndex(logicalIndex) % 2) {
            painter->fillRect(rect, QColor(0, 0, 0, 30));
        }
    } else {
        QHeaderView::paintSection(painter, rect, logicalIndex);
    }
}

优点是,它尊重其父级交替行的设置并使用 visualIndex,以便它正确显示在屏幕上。缺点是,文字也有点淡出。此外,行选择可能在此之后失败或需要添加。

更恰当地说,可以通过在其中使用以下方法定义 QStyle(同样已经建议)来实现效果。

void AlternatingHeaderStyle::drawControl(
        ControlElement element,
        const QStyleOption *option,
        QPainter *painter,
        const QWidget *widget
) const {
    painter->save();
    switch (element) {
        case CE_HeaderSection:
            {
                const QStyleOptionHeader *headerOptionPtr(qstyleoption_cast<const QStyleOptionHeader *>(option));
                if (headerOptionPtr && (headerOptionPtr->orientation == Qt::Vertical)) {
                    QProxyStyle::drawControl(element, option, painter, widget);

                    QAbstractItemView* abstractView(qobject_cast<QAbstractItemView*>(widget->parent()));
                    if (abstractView && abstractView->alternatingRowColors()) {
                        const QHeaderView *verticalHeader(qobject_cast<const QHeaderView *>(widget));
                        if (verticalHeader && verticalHeader->visualIndex(headerOptionPtr->section) % 2) {
                            painter->fillRect(option->rect, QColor(0, 0, 0, 30));
                        }
                    }
                } else {
                    QProxyStyle::drawControl(element, option, painter, widget);
                }
            }

        default:
            QProxyStyle::drawControl(element, option, painter, widget);
            break;
    }
    painter->restore();        
}