c++ - 更改单个 QTabWidget 选项卡的颜色
问题描述
我想改变单个标签的颜色,请看下面的截图。选项卡FOO_SUP
应该是红色的(现在只有按钮是),所有其他的都不是。
对于文本颜色,有bar->setTabTextColor(index, QColor(Qt::red))
,但不是整个选项卡。为选项卡小部件设置选项卡样式表会更改所有选项卡的颜色。
我在这里找到了一个样式表来更改选项卡颜色:https ://stackoverflow.com/a/21687821/356726但不适用于单个选项卡,我还需要能够在运行时决定选项卡是否为红色。
为了清楚起见,下面的小部件应保持黑色,选项卡只有红色。
解决方案
一种选择是实现您自己的标签栏(如此处所述)。
无论如何,我发现使用代理样式更有用和更清晰,因为它允许您部分覆盖绘画,而无需使用标签栏的继承。它还允许您轻松地将新样式应用于现有控件。
它可以是这样的:
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));
重要提示:此解决方案的主要缺点是它不能与现有的选项卡样式表很好地混合:您必须禁用/注释样式表QTabBar::tab
才能应用样式。
推荐阅读
- ios - 在swift中使用数字数组和算术运算符数组进行数学计算
- c# - Asp.net core web api 显示页面
- html - 当我当前在子目录中时如何在根目录中引用 index.html
- vue.js - 如何更新 vuetify mdi 图标?(Nuxt.js)
- r - Roxygen 文档:图片未显示
- java - Appium:ClassNotFoundException:org.openqa.selenium.remote.internal.ApacheHttpClient$Factory
- c++ - 在 OpenGL 和 SDL 中使用多线程
- mysql - 这些 sql 表中的平均 year_max - year_min 是多少?
- dom - 如何检查 DOM .contains?在clojurescript中?
- sql - 创建行满足条件的 Impala 文本表