Чередование цвета фона заголовка QTableView

Используя 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);

К сожалению, это не сработало.

введите описание изображения здесь

1 ответ

Решение

Вы можете реализовать это поведение не с помощью 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 месяцев назад, я наткнулся на это только сейчас.

Ответ Сергея Кулиша очень помог, и я хотел бы предложить два улучшения (снова перезапись 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();        
}
Другие вопросы по тегам