Один из вариантов - реализовать собственную панель вкладок (как объяснено здесь ).
В любом случае, я считаю более полезным и более чистым использование прокси-стиля, поскольку он позволяет частично переопределить рисование без необходимости использовать наследование для панели вкладок. Это также позволит вам легко применять новый стиль к существующим элементам управления.
Это может быть что-то вроде:
class TabBackgroundProxyStyle : public QProxyStyle {
public:
TabBackgroundProxyStyle(const QString& base_style_name, const QMap<QString, QBrush>& backgrounds)
: QProxyStyle(base_style_name),
m_backgrounds(backgrounds) {
}
void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override {
if (element == CE_TabBarTab) {
if (auto tab = qstyleoption_cast<const QStyleOptionTab*>(option)) {
if (m_backgrounds.contains(tab->text)) {
QStyleOptionTab opt(*tab);
opt.palette.setBrush(QPalette::Background, m_backgrounds[tab->text]);
return QProxyStyle::drawControl(element, &opt, painter, widget);
}
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
private:
const QMap<QString, QBrush> m_backgrounds;
};
Чтобы использовать его, просто создайте стиль с соответствующим отображением цвета вкладок (примеры с использованием C ++ 11):
auto theTabWidget = new QTabWidget();
for (int ii = 0; ii < 10; ++ii) theTabWidget->addTab(new QWidget(), QString("Tab %1").arg(ii + 1));
const QMap<QString, QBrush> backgrounds = {
{"Tab 2", QBrush(Qt::red)},
{"Tab 3", QBrush("#c0b050")},
};
theTabWidget->tabBar()->setStyle(new TabBackgroundProxyStyle("", backgrounds));
Если ваш пользовательский интерфейс позволяет изменять текст вкладки во время выполнения (например, переводы на лету или текст является именем файла ...), тогда вы должны соответствующим образом изменить карту.
Использование ярлыка вкладки для индексации объясняется тем, что опция стиля не хранит никакой другой прямой информации о вкладке (даже связанной с ней виджетом, потому что QTabBar
отвечает за отображение только вкладок, это не так. контейнер).
Другим вариантом может быть проверка прямоугольника вкладки, который не занимает много времени для панелей вкладок с несколькими десятками вкладок и более универсален, если вы не хотите работать с метками:
class TabBackgroundProxyStyle : public QProxyStyle {
public:
TabBackgroundProxyStyle(const QString& base_style_name, const QMap<int, QBrush>& backgrounds)
: QProxyStyle(base_style_name),
m_backgrounds(backgrounds) {
}
void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override {
if (element == CE_TabBarTab) {
if (auto tab = qstyleoption_cast<const QStyleOptionTab*>(option)) {
auto tabBar = qobject_cast<const QTabBar*>(widget);
for (auto index : m_backgrounds.keys()) {
if (tab->rect == tabBar->tabRect(index)) {
QStyleOptionTab opt(*tab);
opt.palette.setBrush(QPalette::Background, m_backgrounds[index]);
return QProxyStyle::drawControl(element, &opt, painter, widget);
}
}
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
private:
const QMap<int, QBrush> m_backgrounds;
};
Использование:
auto theTabWidget = new QTabWidget();
for (int ii = 0; ii < 10; ++ii) theTabWidget->addTab(new QWidget(), QString("Tab %1").arg(ii + 1));
const QMap<int, QBrush> backgrounds = {
{1, QBrush(Qt::red)},
{4, QBrush("#c0b050")},
};
theTabWidget->tabBar()->setStyle(new TabBackgroundProxyStyle("", backgrounds));
Полный исходный код можно загрузить с https://github.com/cbuchart/stackoverflow/tree/master/54070408-change-color-of-single-qtabwidget-tab
ВАЖНО : основным недостатком этого решения является то, что оно плохо сочетается с существующей таблицей стилей для вкладок: необходимо отключить / прокомментировать таблицы стилей для QTabBar::tab
, чтобы можно было применить стиль.