在 QT 选项卡中设置文本轮廓样式
当我切换系统主题时,我发现主题中的文本具有我不想要的活动选项卡的轮廓。 ¿
我无法想出任何方法来设计该轮廓并使其消失,以便选项卡文本看起来像这样更干净。
这可能吗?我已经尝试过使用 outline: 0;
样式表,但没有任何反应。
也许重新实现绘制事件?但不知道执行此操作的确切代码。任何帮助表示赞赏。
When I switch system themes, I find themes in which the text has an outline that I don’t want, for active tabs.
¿
I cannot figure any way to style that outline and make it disappear so the tabs text will look cleaner like this.
Is this possible? I have tried already with stylesheets using outline: 0;
and nothing happens.
Reimplementing the paint event perhaps? but no idea about the exact code to do it. Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(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 源代码后发现,绘制此框架的代码是样式表不感知的。
我发现效果很好的唯一方法是欺骗样式,让其认为绘制的选项卡根本没有聚焦。我想出的代码是:
在 tabBar() 小部件上设置此类样式会导致使用正确的样式,并且在没有任何焦点矩形的情况下绘制选项卡。 tabBar() 是受保护的方法,因此您需要创建继承 QTabWidget 的类。
虽然这个解决方案有效,但它不能被称为漂亮。这是通过提供虚假信息的作弊方式。我不认为这会导致一些丑陋的工件,因为小部件只是像往常一样绘制自己(非聚焦)。但是,用户通常希望看到键盘焦点实际在哪里(特别是如果所有其他应用程序都在选项卡上显示它),因此可能会令人困惑。如果让我选择,我会更喜欢一致性而不是外表。
正如我在答案的第一部分(编辑之前)中所写的那样,您还可以在选项卡小部件上调用 setFocusPolicy(Qt::NoFocus) ,因此它根本不接受焦点。甚至可能会推荐,例如。如果您的选项卡位于停靠到主窗口的停靠小部件中。
I was browsing qt-sources and i think what you describe is a focus rect. It should be visible only if tab bar has a focus (or does it behave differently?). Removing it would be confusing to user as he would not see currently focused widget when tab-scrolling throught the window. Making tab bar not-focusing at all might be a solution, but then user will lose ability to change tabs by keyboard.
If you really want to remove it, i would suggest to subclass QProxyStyle, and reimplement drawPrimitive method, so for QStyle::PE_FrameFocusRect it doesn't do anything, and for other elements call QProxyStyle::drawPrimitive.
EDIT:
I tested this approach, and it didn't work - when i have a moment i will try to figure out why.
EDIT2:
After long investigation I figured out why QStyle::PE_FrameFocusRect doesn't work. It appears that focus rectangle is drawn by style directly, bypassing proxy styles completely. The smallest reimplementable code is drawPrimitve for CE_TabBarTabLabel element, but it requires painting tab's labels yourself, which really shouldn't be done in multi-style environment, so thiss not the way to go.
After further examination of code for CleanLooks style (I don't seem to have mentioned Ambiance - or am I making stupid mistake here?) I am sure that qt designers didn't allow such surgical approach to styles - if style wants to paint a frame, there is little to be done to prevent it.
Playing with palette colors to make such frame to "blend in" is almost impossible because other styles might interpret those values differently, causing even worse look. Cleanlooks dreives almost all colors used from palette's button color and it's darker() or lighter() versions, so even for one style it is impossible.
I also tried to see if I can get rid of this frame using qt-stylesheet engine, but whatever stylesheets I used, frame was still drawn without noticable change. After looking int qt source code again it turned out that code drawing this frame is stylesheet-unaware.
The only aproach that I found working quite well, was to cheat style into thinking that drawn tab is not focused at all. Code I came up with is:
Setting such style on tabBar() widget causes right style to be used, and tab is drawn without any focus rectangles. tabBar() is protected method, so you will need to create class inherinig QTabWidget.
While this solution works, it cannot be called pretty. It is cheating style, by providing false information. I don't think it will lead to some ugly artifacts, as widget is just drawing itself as usual (non-focused). However, user usually expects to see where keyboard-focus actually is (especially if all other apps are showing it on tabs), so it might be confusing. If I were to choose, I would prefer consitency over looks.
As I have written in the first part of my answer (before edits), you can also call setFocusPolicy(Qt::NoFocus) on your tab widget, so it simply doesn't accept focus at all. It might be even reccomended eg. if your tabs are in dock widgets docked to main window.