吐槽:没想到在前端仅需一个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),然后绘制路径,同时颜色也需逐渐过渡变淡,终极模拟出阴影效果。
绘制完后,再改变下移动位置,绘制另一层阴影。
大致代码如下:
终极的实现效果如下:
可以看到上方会有部分阴影溢出,下侧没有是由于超出组件边界了。
第三步由于上一步的操作溢出了部分阴影,于是须要肃清掉。
常见的方法是利用setMask设置一个遮罩,但由于mask的内部实现问题,对付含有圆角的图案,实现效果会有较为严重的锯齿,大致代码为self.setMask(path.toFillPolygon().toPolygon()),将其插入阴影绘制前即可。如下:
用原路径做遮罩
可通过将路径扩大两像素,然后移动罩住原图案,将扩大路径设为遮罩,可一定程度肃清锯齿。如图所示:
大致代码如下:
此时效果为:
用扩大路径作为遮罩
可以看出锯齿问题已经改进很多,但放大细看还是有许多锯齿。
另一种方法也可以肃清溢出,并且险些没有锯齿,即设置剪切路径setClipPath(推举)。这种方法不须要再创立一条路径,直接用原路径即可,终极完全代码如下:
终极效果展示:
设置剪切路径
险些实现了原设计效果。
如果你有其它好的实现办法,也可以评论参考下。