当前位置:网站首页>Qt滚动条(QScrollBar)圆角样式问题跟踪
Qt滚动条(QScrollBar)圆角样式问题跟踪
2022-08-10 05:39:00 【KumaNPC】
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;”也可以解决,可以根据情况实际自己选择。
原理分析:
到此已经解决了问题,不过有两个问题还需要再回答。
- Qt::WA_OpaquePaintEvent 代表什么意思?
文档里解释,该属性指示窗口在收到重绘事件时会绘制整个区域,可以避免重绘前频繁擦除背景,在不支持双缓冲技术的系统上减少闪烁之类的。而黑色实际是Windows窗口管理系统上的空颜色。
所以开启该属性后,因为样式的圆角,圆角外的区域没有按规则绘制有效像素,所以就是黑色的。 - 设置 border-style 能解决的原因是什么?
因为该样式会关闭 Qt::WA_OpaquePaintEvent 属性,可以通过 QWidget::testAttribute 验证。
在Qt的源码里,QStyleSheetStyle::polish 也有对应的逻辑:
判断比较多,该例子中在 rule.boder()->isOpaque() 里面有对 border 样式判断,solid 样式恰好返回了 false,如果没有设置则是 none,可能返回true,具体其他情况就没有详细研究。
边栏推荐
猜你喜欢
随机推荐
Qt信号槽与事件循环的关系
Talking about the realization idea of "frame" of "frame synchronization online game"
pthread编程重要知识点
【论文解读】滴滴智能派单-KDD2018 Large-Scale Order Dispatch in On-Demand Ride-Hailing
全网可达并设备加密
XV6 swtch.S详解
markdown使用技巧
Unity瓦片地图取消部分刚体效果
Kernel performance analysis summary
什么是代理ip?市面上好用的代理软件有哪些
Myunity框架笔记
DRM Memory Management
Unity2D动画生成操作(简单)
H3C文档NAT专题
网页安全证书错误但无法安装证书的解决办法
ACPI知识(高级配置和电源接口)
关于研究鼠标绘制平滑曲线的阶段总结
如何实现网格建造系统
netlink IPC
Easy to master Unity of eight prior to rendering