QHeaderView стиль каждого столбца

Я пытаюсь изменить стиль заголовка QTreeWidget,

Я обнаружил, что могу редактировать QHeaderView::section и там, редактировать фон, цвета, границы …

Тем не менее, я хотел бы отдельно редактировать заголовки столбцов. Я нашел на документация что мы можем использовать ::first, ::last

Есть ли способ точно указать другой раздел (с чем-то вроде [index = 3] например)?.

1

Решение

Нет, нет способа изменить внешний вид раздела заголовка с помощью таблиц стилей, кроме использования ::first, ::last, ::middle, QStylesheetStyle (тот, который используется при загрузке таблицы стилей) реализует только эти состояния.

Чтобы решить эту проблему, вы можете использовать QHeaderView что реализует его paintEventили вариант, который я рекомендую вам: использовать собственный стиль ( QProxyStyle это хороший вариант, поскольку он позволяет вам реализовать только те функции, которые вы хотите, и наследовать остальное от база стиль). Вы должны повторно реализовать drawControl метод специально для CE_Header элемент:

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

Заметка: Мне удалось заставить его работать с слияние только стиль Кажется, что окна Стиль реализует свою собственную цветовую схему для заголовков. Если вы хотите использовать такой стиль, то вы должны вручную нарисовать заголовок (в том же drawControl, нет необходимости повторно внедрять QHeaderView).

Чтобы использовать собственный стиль просто qApp->setStyle(new MyProxyStyle("fusion")); (берет слияние как базовый стиль).

Результат

заголовок


ОЧЕНЬ ВАЖНОЕ ПРИМЕЧАНИЕ: вы должны знать, что, как указано в документации, вы не могу использовать обычай QStyle и таблицы стилей одновременно:

Предупреждение: таблицы стилей Qt в настоящее время не поддерживаются для пользовательских подклассов QStyle. Мы планируем решить эту проблему в следующем выпуске.


Предыдущий ответ

По ошибке я ранее ответил на вопрос QTabBar проблема, которая оказывается очень похожей: невозможно использовать таблицу стилей для настройки данной вкладки, кроме некоторых предопределенных (например, первой или последней). Мы должны либо повторно реализовать QTabBar или используйте собственный стиль (как и раньше). Я оставляю решение для него на всякий случай, если оно пригодится кому-то еще.

Сложность в том, что опция стиля не имеет никакой информации об индексе вкладки, поэтому вам нужно как-то это выяснить. Я использую x положение вкладки (доступно как из опции, так и из QTabBar) эффективный индикатор для сопоставления вкладок. Если ваша вкладка отображается вертикально, вы должны использовать y координаты вместо этого, и если панель вкладок многострочная, то используйте всю rect,

Полный код минимального стиля прокси будет:

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

Причина использования разных цветовых ролей при настройке кисти заключается в том, что разные стили используют разные роли при рисовании раздела (слияние стиль использует QPalette::Button для фона, в то время как окна использования QPalette::Background вместо). Другие роли позволят вам настроить границы и цвета текста, например.

Результаты

С слияние стиль:

слияние

С окна стиль:

окна

2

Другие решения

В некоторых простых случаях вы можете изменить цвета раздела QHeaderView, используя методы QAbstractItemModel и роли:

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

По вопросам рекламы [email protected]