Qt滚动条(QScrollBar)圆角样式问题跟踪

本文介绍了在Qt中使用样式表设置圆角滚动条时遇到的黑色背景问题。通过分析样式表和源码,发现问题是由于Qt::WA_OpaquePaintEvent属性导致的。关闭该属性或设置'border-style:solid'可解决问题。文章探讨了Qt::WA_OpaquePaintEvent的作用以及设置border-style的影响,并提供了解决方案。
摘要由CSDN通过智能技术生成

Qt使用样式表设置圆角滚动条的黑色背景问题

今天在知乎上看到一篇文章,描述使用样式表设置圆角滚动条时,圆角四周会有黑色区域而非透明,文章里最后借用 QSlider 来实现圆角滚动条。

我好奇 Qt 居然会出现这样的Bug,就研究了一下,顺便做个记录。


设置圆角样式:

QScrollBar 有一些子控件区域,handle 为滑块, add-line、sub-line 默认是滚动条两侧箭头区域,add-page、sub-page 是滑块两侧区域,使用以下样式表设置圆角,除了滑块与主背景,都设置为透明:

QScrollBar:horizontal{
    background: #309AB8;
    border-radius: 15px;
    min-height: 30px;
    max-height: 30px;
}
QScrollBar::handle:horizontal{
    background: #FFFFFF;
    border-radius: 15px;
    min-width: 30px;
}
QScrollBar::add-page,
QScrollBar::sub-page{
    background: transparent;
}
QScrollBar::add-line,
QScrollBar::sub-line{
    background: transparent;
}

结果如下图所示,确实周围出现黑色像素:
圆角样式


原因跟踪:

一开始尝试调整子控件的样式,无解,而且圆角四周会出现奇怪的刷新问题。

重写 QScrollBar::paintEvent,使用老方法自绘。发现即使不绘制子控件,也是会有黑色像素,调试源码猜测是绘制边框的问题。

在样式表里设置一下 “border: 1px solid transparent”,黑色像素居然没有了,只不过边框歪歪扭扭对不齐。

调试源码又看不明白源码是怎么绘制边框的,便在 paintEvent 什么都不做,发现整个滚动条区域居然都是黑色的:
黑色
这种情况在 Qt 中并不多见,经常自绘或者写无边框窗口总会遇到,无非是几个特定属性,查看 QScrollBar 源码的构造函数发现:
在这里插入图片描述
尝试手动关闭该属性,黑色背景消失。


解决方案:

所以,根本原因在 Qt::WA_OpaquePaintEvent 被默认开启了,关闭掉就行了。测试过程中发现设置 “border-style: solid;”也可以解决,可以根据情况实际自己选择。

原理分析:

到此已经解决了问题,不过有两个问题还需要再回答。

  1. Qt::WA_OpaquePaintEvent 代表什么意思?
    文档里解释,该属性指示窗口在收到重绘事件时会绘制整个区域,可以避免重绘前频繁擦除背景,在不支持双缓冲技术的系统上减少闪烁之类的。而黑色实际是Windows窗口管理系统上的空颜色。
    所以开启该属性后,因为样式的圆角,圆角外的区域没有按规则绘制有效像素,所以就是黑色的。
  2. 设置 border-style 能解决的原因是什么?
    因为该样式会关闭 Qt::WA_OpaquePaintEvent 属性,可以通过 QWidget::testAttribute 验证。
    在Qt的源码里,QStyleSheetStyle::polish 也有对应的逻辑:
    源码
    判断比较多,该例子中在 rule.boder()->isOpaque() 里面有对 border 样式判断,solid 样式恰好返回了 false,如果没有设置则是 none,可能返回true,具体其他情况就没有详细研究。
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值