c++ - 更改单个 QTabWidget 选项卡的颜色

标签 c++ qt qtabwidget

我想更改单个选项卡的颜色,请参见下面的屏幕截图。 FOO_SUP选项卡应该是红色的(现在只有按钮是红色的),其他所有选项卡都不是。

Example

对于文本颜色,有 bar->setTabTextColor(index, QColor(Qt::red)),但不是整个选项卡。设置选项卡小部件的选项卡样式表会更改所有选项卡的颜色。

我在这里找到了一个样式表来更改选项卡颜色:https://stackoverflow.com/a/21687821/356726但不适用于单个选项卡,我还需要能够在运行时决定选项卡是否为红色。

为了明确起见,下面的小部件应保持黑色,选项卡仅红色。

最佳答案

一种选择是实现您自己的标签栏(如 here 所述)。

无论如何,我发现代理样式的使用更有用、更简洁,因为它允许您部分覆盖绘画,而无需使用选项卡栏的继承。它还允许您轻松地将新样式应用到现有控件。

它可以是这样的:

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

如果您的用户界面允许选项卡的文本在运行时更改(例如,即时翻译,或者文本是文件名...),那么您必须相应地修改 map 。

使用选项卡的标签进行索引是因为样式选项不存储有关选项卡的任何其他直接信息(甚至不存储关联的小部件,因为 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 的样式表为了能够应用该样式。

关于c++ - 更改单个 QTabWidget 选项卡的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54070408/

相关文章:

c++ - std::cout 不适用于结构的重载 '<<' 运算符

python 如何从 QTabwidget 获取选项卡名称

使用样式表时的 QTabWidget tabPosition

c++ - 如何将 uint8_t 放入 char 数组中?

当数组大小太大时 C++ 程序停止工作

c++ - 如何使用 QDnsLookup 类查找网站的 IP 地址?

c++ - 我们可以通过 D 总线访问数据成员和对象指针吗?

python - 如何更新作为类创建的 PyQt5 选项卡之间的值

c++ - 如何更改此 vector 函数以接受更多元素?

c++ - Qt 框架——我可以(合法地)使用 qmake 而不是 Qt 创建商业应用程序吗?