Qt QWidget 抗锯齿圆角窗口的一个实现方案(支持子控件)

这篇具有很好参考价值的文章主要介绍了Qt QWidget 抗锯齿圆角窗口的一个实现方案(支持子控件)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QWidget独立窗口抗锯齿圆角窗口的一个实现方案

由于 QWidget::setMask 接口设置圆角不支持抗锯齿,所以通常会使用透明窗口加圆角背景,但圆角背景不能满足对子控件的裁剪,子控件与圆角区域重叠的部分还是能显示出来。当然对于大多数窗口,留出足够的边距也是可以接受。

对一些特殊场景,比如QComboBox的列表框,UI设计师强烈要求圆角,列表与它的容器不能有边距,常规办法就很难做到。笔者在经过长时间的研究,有了一个可能的方案。

最终实现效果如下图,可以看到,列表项区域,滚动条区域也能够正常显示圆角。
Qt QWidget 抗锯齿圆角窗口的一个实现方案(支持子控件)

注意,该方案可能不适用一些场景:

  1. 特殊的平台或Qt配置
  2. 复杂窗口且有性能要求
  3. 窗口尺寸较大(可以优化)
  4. 有嵌入式窗口、OpenGL、QWindow等

方案

基本原理

Qt的每个独立窗口,默认都是在一张图片上,层叠绘制所有子控件。通常我们自绘控件时,几乎不会使用QPainter::setCompositionMode设置其他混合模式,会出现比较奇怪的效果。但如果使用透明背景窗口,使用混合模式其实跟在QPixmap或QImage上绘制一样。

另外一点,当一个控件重绘时,由于底层的绘制会影响到上层透明合成,所以Qt会从下到上按顺序绘各个控件的脏区域。

所以理论上,如果在一个窗口上增加一个全尺寸的遮罩,重绘时使用混合模式就可以实现对一些像素的清除,且支持抗锯齿。

代码步骤

  1. 创建一个QWidget作为遮罩

    遮罩置于顶层,鼠标设置透传(WA_TransparentForMouseEvents)

    遮罩跟随窗口尺寸大小同步变化,保持一致。安装事件过滤器即可(installEventFilter)

  2. 重写paintEvent,利用混合模式清除圆角像素

    以下绘制逻辑比较直接,建议优化

	//创建一个图片,填充透明色
	QPixmap pix(this->size());
	pix.fill(QColor(0,0,0,0));
	// 在改图片上填充一个圆角区域,需要设置抗锯齿
	QPainter painter(&pix);
	painter.setRenderHint(QPainter::Antialiasing);
	QPainterPath path;
	//这里圆角区域需要根据dpi、size调整
	path.addRoundedRect(QRectF(pix.rect()).adjusted(0.5, 0.5, -0.5, -0.5), 10, 10); 
	painter.fillPath(path, Qt::white);
	painter.end();
	// 在窗口上绘制该圆角图片
	painter.begin(this);
	painter.setRenderHint(QPainter::Antialiasing);
	// 该混合模式会根据source像素的透明度,调整目标的透明度
	painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
	painter.drawPixmap(0, 0, pix);
	// 恢复默认混合模式,绘制边框,如果没有则不用
	painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
	painter.setPen(QPen(QColor(0xCA64EA), 1.0));
	painter.drawPath(path);

优化方向

  1. 性能优化

    上面的示例,使用了一整张图片对窗口像素进行混合模式的运算,且每次子控件重绘都会引起遮罩的重绘,性能比较差。可以考虑仅在四周设置圆角的遮罩。

  2. 圆角绘制优化

    本文使用了一个不透明的圆角区域对窗口设置裁剪,圆角的参数是固定在代码里的。实际QSS是可以设置窗口的圆角,因此可以借助QSS来生成一张圆角图片,就避免代码里包含固定数值。

    具体实现原理可以参考之前的文章,这里不具体展示了:
    QComboBox文字居中的一种解决办法
    Qt实现一个支持QSS的Switch Button
    Qt借助隐藏控件和QSS绘制重复元素文章来源地址https://www.toymoban.com/news/detail-423736.html

到了这里,关于Qt QWidget 抗锯齿圆角窗口的一个实现方案(支持子控件)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ubuntu下 利用QT 实现嵌入另外一个程序到当前窗口

    查看当前应用窗口名称

    2024年02月11日
    浏览(51)
  • 【QT】QWidget实现柱状图

    在名为 w_bar20auto1 的 QWidget 实现柱状图

    2024年02月02日
    浏览(65)
  • 如何用Qt实现一个无标题栏、半透明、置顶(悬浮)的窗口

    在Qt框架中,要实现一个无标题栏、半透明、置顶(悬浮)的窗口,需要一些特定的设置和技巧。废话不多说,下面我将以DrawClient软件为例,介绍一下实现这种效果的四个要点。 要点一:移除标题栏(去除关闭、最小化、最大化按钮) 在窗口的构造函数中设置窗口的样式,

    2024年02月19日
    浏览(38)
  • Qt自定义窗口部件/控件(实现一个十六进制微调框SpinBox)

    在某些情况下,我们发现Qt窗口控件需要更多的自定义定制,这些定制可能要比它在Qt设计师里可设置的属性或者对它调用的那些函数更多一些。一个简单而直接的解决方法就是对相关的窗口部件类进行子类化并且使它能够满足我们的需要。 本文主要是通过实现一个十六进制微调

    2024年02月11日
    浏览(43)
  • 《QT从基础到进阶·三十六》QWidget实现收缩栏的效果

    功能: 1、可以在收缩栏插件中添加界面 2、可以把界面展开或收缩 3、可以用鼠标拖动界面改变界面的排放顺序 1、可以在收缩栏插件中添加界面 参数1:插入的界面指针 参数2:插入的界面标题 参数3:插入的界面图标 demo: 在收缩栏插件中添加两个界面 2、界面展开或收缩

    2024年02月05日
    浏览(69)
  • Unity 圆角矩形Shader实现(支持长方形)(只写两行)

    相信很多小伙伴都会遇到做 圆角矩形 的需求,网上的shader还不明白是怎么实现的,甚至还有一部分是错误的,本文讲从原理到代码讲解 圆角矩形shader 的实现 想要实现一个圆角矩形,常见的是抽象成一个数学模型,如下图紫色区域,就是我们应该保留的区域,为了更准确的

    2024年02月04日
    浏览(47)
  • 在ARM板上实现qt虚拟键盘 Qwidget实现 官方虚拟键盘、第三方虚拟键盘qtvirtualkeyboard //Qwidget最简单但效果不是最好

    在使用qt的虚拟键盘以前,我的开发板qt环境中并没有安装虚拟键盘库,所以这里还会顺便介绍如何在开发板上已安装qt环境的前提下,继续更新qt的组件。 开发板qt版本:5.15.2 在这里,我默认你已经有自己动手交叉编译过qt源码了,否则你将缺少部分细节和前置知识。首先在

    2024年04月09日
    浏览(386)
  • 已经创建完成的QWidget窗口更改为QDialog窗口

    描述:经常性的创建窗口为QWidget,后期想做模态窗口QWidget明显不如QDialog使用方便,所以做个窗口更改教程。 方法: 1.更改父类为QDialog 2. 使用notepad++打开ui文件  3.更改class为QDialog  

    2024年02月09日
    浏览(42)
  • 【CSS】透明背景的圆角渐变边框实现方案

    css的渐变边框可以用下面方式实现 css的圆角边框可以用下面方式实现 那想要实现一个圆角的渐变边框呢,可能会以为,两个都用上不就可以了,但事实是,这两个属性并不兼容,所以要实现一个圆角的渐变边框,就得需要曲线救国的方法了 最终效果图    

    2024年02月13日
    浏览(72)
  • FPGA基于XDMA实现PCIE X4通信方案 提供工程源码和QT上位机程序和技术支持

    PCIE(PCI Express)采用了目前业内流行的点对点串行连接,比起 PCI 以及更早期的计算机总线的共享并行架构,每个设备都有自己的专用连接,不需要向整个总线请求带宽,而且可以把数据传输率提高到一个很高的频率,达到 PCI 所不能提供的高带宽,是目前各行业高速接口的优

    2023年04月24日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包