【问题标题】:Styling the text outline in QT‘s tabs在 QT 的选项卡中设置文本轮廓的样式
【发布时间】:2011-09-20 21:35:41
【问题描述】:

当我切换系统主题时,我发现主题中的文本具有我不想要的轮廓,用于活动选项卡。 ¿

我想不出任何方法来设置该轮廓的样式并使其消失,以便标签文本看起来像这样更干净。

这可能吗?我已经尝试过使用outline: 0; 的样式表,但没有任何反应。

也许重新实现绘画事件?但不知道执行此操作的确切代码。任何帮助表示赞赏。

【问题讨论】:

  • 我会如实离开主题。如果用户喜欢带有这些轮廓的主题,那么我认为用户会更喜欢统一的应用程序外观。
  • @Blender 首先我想告诉你,你是我最喜欢的 3D 建模应用程序。我已经使用你很多年了。好吧,关于您的评论,奇怪的是 GTK 应用程序不会在 QT 应用程序时显示此大纲。其实我也不知道是谁的错。
  • 大声笑,谢谢。我不再使用它了(没有理由,说实话),但它仍然是我最喜欢的 3D 建模/动画/模拟程序,钱买不到。至于选项卡,我得到了 GTK+ 应用程序的概要(这是 Nautilus):i.imgur.com/dSrQs.png。但我可以看到我能做什么......
  • 大声笑,不客气。至于标签......你用的是什么风格?我正在使用 Clearlooks。
  • Blender 的第一条评论+1。不玩主题是一个好习惯。但是如果你真的想控制这个小东西,你就必须继承 QStyle 并查看QTabBar::initStyleOption() 源代码来弄清楚这个大纲是如何以及为什么出现的

标签: qt text tabs stylesheet outline


【解决方案1】:

我正在浏览 qt-sources,我认为您所描述的是焦点矩形。只有当标签栏有焦点时它才应该是可见的(或者它的行为是否不同?)。删除它会使用户感到困惑,因为当标签滚动通过窗口时,他不会看到当前聚焦的小部件。使标签栏完全不聚焦可能是一种解决方案,但用户将失去通过键盘更改标签的能力。

如果你真的想删除它,我建议继承 QProxyStyle,并重新实现 drawPrimitive 方法,所以对于 QStyle::PE_FrameFocusRect 它什么都不做,而对于其他元素调用 QProxyStyle::drawPrimitive。

编辑:

我测试了这种方法,但它不起作用 - 当我有时间时,我会尝试找出原因。

EDIT2:

经过长时间的调查,我弄清楚了为什么 QStyle::PE_FrameFocusRect 不起作用。看起来焦点矩形是直接按样式绘制的,完全绕过了代理样式。最小的可重实现代码是 CE_TabBarTabLabel 元素的 drawPrimitve,但它需要自己绘制标签的标签,这在多样式环境中确实不应该这样做,所以这不是要走的路。

在进一步检查 CleanLooks 风格的代码后(我似乎没有提到 Ambiance - 还是我在这里犯了愚蠢的错误?)我确信 qt 设计师不允许对风格进行这种外科手术 - 如果风格想要画一个框架,几乎没有什么可以阻止它。

使用调色板颜色使这种框架“融入”几乎是不可能的,因为其他样式可能会以不同的方式解释这些值,从而导致更糟糕的外观。 Cleanlooks 从调色板的按钮颜色中提取了几乎所有使用的颜色,并且它是较暗()或较亮()版本,因此即使是一种样式也是不可能的。

我还尝试查看是否可以使用 qt-stylesheet 引擎摆脱这个框架,但是无论我使用什么样式表,框架仍然被绘制而没有明显的变化。再次查看 int qt 源代码后,发现绘制此框架的代码是样式表不知道的。

我发现工作得很好的唯一方法是欺骗风格,认为绘制的标签根本没有重点。我想出的代码是:

class myStyle: public QProxyStyle{
public:
    myStyle(QStyle* baseStyle)
        :QProxyStyle(baseStyle){}

    virtual void drawControl ( ControlElement element, const QStyleOption * option, QPainter * painter, const QWidget * widget = 0 ) const{

        if (element == CE_TabBarTabLabel){
            if (const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(option)) {
                if (tb->state & State_HasFocus){
                    QStyleOptionTab t(*tb);
                    t.state = t.state^State_HasFocus;
                    QProxyStyle::drawControl(element, &t, painter, widget);
                    return;
                }
            }
        }
        QProxyStyle::drawControl(element, option, painter, widget);
    }
};

在 tabBar() 小部件上设置这样的样式会导致使用正确的样式,并且在没有任何焦点矩形的情况下绘制选项卡。 tabBar() 是受保护的方法,因此您需要创建继承 QTabWidget 的类。

虽然这个解决方案有效,但它不能称为漂亮。这是作弊风格,通过提供虚假信息。我不认为它会导致一些丑陋的工件,因为小部件只是像往常一样绘制自己(非聚焦)。但是,用户通常希望看到键盘焦点的实际位置(特别是如果所有其他应用程序都在选项卡上显示它),因此可能会造成混淆。如果让我选择,我更喜欢一致性而不是外表。

正如我在答案的第一部分(编辑之前)中所写,您还可以在您的选项卡小部件上调用 setFocusPolicy(Qt::NoFocus),因此它根本不接受焦点。它甚至可能被推荐,例如。如果您的标签位于停靠在主窗口的停靠小部件中。

【讨论】:

  • 我会尽可能地尝试这个,现在你应该为你所做的所有工作获得 500 分。感谢您提供这些有用的信息。
猜你喜欢
  • 2012-05-04
  • 2021-09-14
  • 1970-01-01
  • 2017-01-10
  • 2010-10-14
  • 2013-02-01
  • 2012-10-28
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多