QTableView标头背景颜色交替

时间:2018-12-17 10:45:26

标签: c++ qt qtstylesheets

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

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);

不幸的是,它没有用。

enter image description here

2 个答案:

答案 0 :(得分:0)

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

#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);

答案 1 :(得分:0)

即使如此,这个问题在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();        
}