Я пытаюсь изменить стиль заголовка QTreeWidget
,
Я обнаружил, что могу редактировать QHeaderView::section
и там, редактировать фон, цвета, границы …
Тем не менее, я хотел бы отдельно редактировать заголовки столбцов. Я нашел на документация что мы можем использовать ::first
, ::last
…
Есть ли способ точно указать другой раздел (с чем-то вроде [index = 3]
например)?.
Нет, нет способа изменить внешний вид раздела заголовка с помощью таблиц стилей, кроме использования ::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
вместо). Другие роли позволят вам настроить границы и цвета текста, например.
Результаты
С слияние стиль:
С окна стиль:
В некоторых простых случаях вы можете изменить цвета раздела 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);