最近在使用PySide6开发一样东西的时候,需要实现一个带有内阴影的异形组件,但找了很多资料文档,都没有多好的解决方案;就连万能的AI也没能给我很好的答案,最终自己瞎捣鼓了一个方案,自认为效果还不错,特此分享。
吐槽:没想到在前端仅需一个box-shadow即可实现的效果在PySide6中竟然如此难实现,直至今日,官方竟也没有一个多好的解决方案(难度QT没有这样的需求,还是PySide6没有,当然也可能是我不知道)
小声**: QGraphicsDropShadowEffect也并不好用,还只能实现外阴影,效果也不强大
预计实现效果
这就是前端的设计图,需用PySide6实现,最终效果虽稍有偏差,但还算说得过去。
其对应的box-shadow为inset 3px 3px 6px 0px rgba(255, 255, 255, 0.7),inset -3px -3px 6px 0px rgba(0, 0, 0, 0.3);,为黑白两层内阴影构成。
第一步首先需绘制一个目标图形,由于是异形,非寻常图形,所以需自己重写paintEvent,大致代码如下
实现的效果图如下:
自绘制基础图形
其可以根据Frame的size自动绘制对应大小的图案
第二步实现阴影,由于是异形且需实现内阴影,故QGraphicsDropShadowEffect就用不了了
那么能想到的方法就只有自己绘制了,常见的方法主要有两种,一种是准备好对应的阴影素材图片,然后一张张绘制到对应位置;另一种就是自己沿着路径一层层绘制,模仿阴影效果(这也是本文采取方案)。
这里主要绘制了六层,大致如下图所示,每次使用translate对角移动下位置(距离需改小点,这里为0.8),然后绘制路径,同时颜色也需渐渐过渡变淡,最终模仿出阴影效果。
绘制完后,再改变下移动位置,绘制另一层阴影。
大致代码如下:
最终的实现效果如下:
可以看到上方会有部分阴影溢出,下侧没有是由于超出组件边界了。
第三步由于上一步的操作溢出了部分阴影,于是需要消除掉。
如下:
用原路径做遮罩
可通过将路径扩大两像素,然后移动罩住原图案,将扩大路径设为遮罩,可一定程度消除锯齿。如图所示:
大致代码如下:
此时效果为:
用扩大路径作为遮罩
可以看出锯齿问题已经改善很多,但放大细看还是有许多锯齿。
这种方法不需要再创立一条路径,直接用原路径即可,最终完整代码如下:
最终效果展示:
设置剪切路径
几乎实现了原设计效果。
如果你有其它好的实现方式,也可以评论参考下。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved