Изменить цвет одной вкладки QTabWidget - PullRequest
0 голосов
/ 07 января 2019

Я хочу изменить цвет одной вкладки, см. Скриншот ниже. Вкладка FOO_SUP должна быть красной (сейчас только кнопка), все остальные - нет.

Example

Для цвета текста есть bar->setTabTextColor(index, QColor(Qt::red)), но не вся вкладка. Настройка таблицы стилей вкладок для виджета вкладок изменяет цвет всех вкладок.

Я нашел здесь таблицу стилей для изменения цвета вкладки: https://stackoverflow.com/a/21687821/356726, но не для одной вкладки, также мне нужно иметь возможность во время выполнения решить, будет ли вкладка красной или нет.

Просто чтобы прояснить, виджет ниже должен оставаться черным, а вкладка только красным.

1 Ответ

0 голосов
/ 07 января 2019

Один из вариантов - реализовать собственную панель вкладок (как объяснено здесь ).

В любом случае, я считаю более полезным и более чистым использование прокси-стиля, поскольку он позволяет частично переопределить рисование без необходимости использовать наследование для панели вкладок. Это также позволит вам легко применять новый стиль к существующим элементам управления.

Это может быть что-то вроде:

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, чтобы можно было применить стиль.

...