【PyQt】(自定义类)阴影遮罩-升级版

这是之前发的代码(自定义类)阴影遮罩的升级版。
升级就升级在,优化了对非矩形控件的遮盖效果,例如圆角按钮,以及默认方法不满足时可以传入其他的遮盖方法。



自定义阴影遮罩Mask:

class Mask(QWidget):__exclude=None__color=Noneclicked=pyqtSignal(object)#单击遮罩时触发,以实现其他操作def __init__(self,parent=None,*exclude,color=QColor(0,0,0,128)):super().__init__(parent)exclude=list(exclude)for pst in range(len(exclude)):if(type(exclude[pst])!=tuple):exclude[pst]=(exclude[pst],self.Trans_WidMask_Default)else:if(len(exclude[pst])<2):exclude[pst]=(exclude[pst][0],self.Trans_WidMask_Default)elif(type(exclude[pst][1])==bool):if(exclude[pst][1]==False):exclude[pst]=(exclude[pst][0],self.Trans_WidMask_Default)else:exclude[pst]=(exclude[pst][0],self.Trans_WidMask_Style)self.__exclude=excludeself.__color=colorself.show()self.__wid=QWidget()def mousePressEvent(self,event):self.clicked.emit(self)def paintEvent(self,event):self.resize(self.parent().size())bit=QBitmap(self.size())bit.fill(Qt.black)painter_bit=QPainter(bit)for item,offset in self.__Get_Offset().items():wid,trans=itempix=trans(wid)# pix=self.Trans_WidMask_Default(wid)# pix=self.Trans_WidMask_Style(wid)painter_bit.drawPixmap(QRect(offset,wid.size()),pix)painter_bit.end()painter_self=QPainter(self)painter_self.fillRect(0,0,self.size().width(),self.size().height(),self.__color)painter_self.end()self.setMask(bit)def __Get_Offset(self):record={}parent_self=self.parent()for item in self.__exclude:if(not item[0].isVisible()):continuewid=item[0]parent_wid=wid.parent()offset=QPoint(0,0)while (True):offset+=wid.pos()if(not parent_wid):breakif(parent_wid==parent_self):breakwid=wid.parent()parent_wid=wid.parent()if(parent_wid):record[item]=offsetreturn record@classmethoddef Trans_WidMask_Default(self,wid):pix=QPixmap(wid.size())pix.fill(Qt.white)return pix@classmethoddef Trans_WidMask_Style(self,wid):arr=self.Trans_PixToArray(wid.grab())#洪填,将外围填充arr=cv2.cvtColor(arr,cv2.COLOR_RGBA2GRAY)h, w = arr.shape[:2]mask = np.zeros([h+2, w+2],np.uint8)arr_copy=arr.copy()arr=cv2.rectangle(arr,(0,0),(w-1,h-1),(int(arr[0][0]),))cv2.floodFill(arr, mask, (0,0), (0,), (2,), (2,), cv2.FLOODFILL_FIXED_RANGE)#参数是试出来的...懒得研究洪填arr=arr==arr_copyarr=arr*255arr=arr.astype(np.uint8)return self.Trans_ArrayToPix(arr)@staticmethoddef Trans_PixToArray(pix):#pix是RGBA四通道QPixmap。不使用PIL.Image模块h,w=pix.height(),pix.width()buffer = QImage(pix).constBits()buffer.setsize(h*w*4)arr = np.frombuffer(buffer, dtype=np.uint8).reshape((h,w,4))return arr.copy()@staticmethoddef Trans_ArrayToPix(arr):#arr对应四通道图片。不使用PIL.Image模块arr=cv2.cvtColor(arr,cv2.COLOR_RGBA2BGRA)img=QImage(arr.data, arr.shape[1], arr.shape[0], arr.shape[1]*4, QImage.Format_RGBA8888)return QPixmap(img)

测试代码+运行结果:


if __name__=='__main__':import sysfrom PyQt5.QtWidgets import QApplicationapp = QApplication(sys.argv)lb_1=QPushButton("ABCDE")lb_1.setStyleSheet("font-size:150px ; border:2px groove gray;border-radius:50px;padding:2px 4px;border-style: outset;}""QPushButton{background-color: rgb(0, 224, 224);}""QPushButton:hover{background-color:rgb(0, 255, 255); color: black;}""QPushButton:pressed{background-color:rgb(0, 192, 192);border-style: inset;")lb_2=QPushButton("PQRST")lb_2.setStyleSheet("font-size:150px ; background-color:#FF0000")lb_3=QPushButton("XYZ",lb_2)lb_3.setStyleSheet("font-size:50px ; background-color:#FFFF00")win=QWidget()vbox=QVBoxLayout(win)vbox.addWidget(lb_1)vbox.addStretch(1)vbox.addWidget(lb_2)win.show()win.resize(755,400)#【创建阴影遮罩】# msk=Mask(win,lb_1,lb_2,color=QColor(0,0,0,192))# msk=Mask(win,lb_1,lb_3,color=QColor(0,0,0,192))msk=Mask(win,(lb_1,True),lb_3,color=QColor(0,0,0,192))# msk.setParent(None)msk.clicked.connect(lambda msk:msk.hide())#单击隐藏遮罩sys.exit(app.exec())

运行结果

说明:

  1. 与前篇文章(自定义类)阴影遮罩的用法大致一致,是“即用即贴”型,不用时就调用msk.setParent(None)撤走即可。
  2. 简单说明Mask的构造函数Mask(parent=None,*exclude,color=QColor(0,0,0,128))
    exclude元素可以有4种样式:wid、(wid,False)、(wid,True)、(wid,Func),其中wid等价于(wid,False)。
    exclude元素的第二参数如果为False那么将对应调用Mask.Trans_WidMask_Default[普通型],为True将调用Mask.Trans_WidMask_Style[样式表型],当这两种方法都不能满足遮盖需求时,即可自己编写第三种方法并将第二参数设置为该函数。
    上面的说明看不懂没关系,试着运行下测试代码就知道了。
  3. 遮罩单击时会触发clicked信号,用于实现“点击空白位置以取消”的操作。(感觉还不够用的话就自己改Mask代码吧


参考:

  • (自定义类)阴影遮罩:https://blog.csdn.net/weixin_44733774/article/details/134587980
  • QPixmap与numpy.array互转:https://blog.csdn.net/weixin_44733774/article/details/134578487
  • OpenCV中floodfill的使用(洪水填充):https://blog.csdn.net/remakeprogramer/article/details/113724635

未经本人同意不得私自转载。本文发布于CSDN:https://blog.csdn.net/weixin_44733774/article/details/134609775

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/179484.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20 章 多线程

20.1线程简介. 20.2创建线程 2.1继承Thread类 Thread 类是java.lang包中的一个类&#xff0c;从这个类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建立Thread 实例。Thread类中常用的两个构造方法如下: public Thread():创建一个新的线程对象。 public Thre…

数据安全:专业服务与您共同对抗.faust数字勒索的威胁

引言&#xff1a; 在数字世界的幕后&#xff0c;一股黑暗势力悄然崛起。.faust勒索病毒&#xff0c;如同数码时代的黑手党&#xff0c;通过其高度精密的加密技术&#xff0c;正在肆虐用户和组织的数据。本文将深入挖掘.faust的狡猾手法&#xff0c;为您揭示其隐藏在数字背后的…

v-model(双向数据绑定)自动收集数据

v-model 是 Vue 中一个常用的指令&#xff0c;用于实现表单元素与数据的双向绑定。 它的实现原理主要基于以下两个方面&#xff1a; 语法实现&#xff1a; v-model 实际上是 Vue 对 :value 和 input 两个属性的语法糖。当我们在组件中使用 v-model 指令时&#xff0c;Vue 会根…

C++ string类(二)

insert&#xff1a; erase&#xff1a; 常见用法&#xff1a; int main() {string s1("hello world");string s2("gm");s1.insert(5,"x");cout << s1 << endl;s1.insert(6,s1,0);cout << s1 << endl;s1.insert(0,&qu…

Matlab 点云曲率计算(之二)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 之前已经讨论过许多关于计算曲率的问题,这里使用一个通过拟合三次曲面方程的方式来计算曲率,计算过程如下图所示: 二、实现代码 %********

goweb入门教程

本文是作者自己学习goweb时写的笔记&#xff0c;分享给大家&#xff0c;希望能有些帮助 前言&#xff1a; 关于web&#xff1a;本质 ​ ​ web中最重要的就是浏览器和服务器的request(请求)和response(响应)&#xff1b; ​ 一个请求对应一个响应。 一个请求对应一个响应&…

11-28渗透

用nmap扫描靶机1进行主机发现 已知靶机1的主机在172.16.17.0/24下 扫描结果如下 根据扫描结果看开启的服务怀疑172.16.17.177是靶机1 浏览器访问172.16.17.177页面得到如下 我们知道织梦cms系统默认管理路径是dede&#xff0c;登陆管理后台可以通过地址172.16.17.177/dede/i…

隐式类型转化

1. 2. 3. 4. 5. 6. 7. 8.

Flutter开发type ‘Future<int>‘ is not a subtype of type ‘int‘ in type cast错误

文章目录 问题描述错误源码 问题分析解决方法修改后的代码 问题描述 今天有个同事调试flutter程序时报错&#xff0c;问我怎么解决&#xff0c;程序运行时报如下错误&#xff1a; type ‘Future’ is not a subtype of type ‘int’ in type cast 错误源码 int order Databas…

PTA-6-48 使用面向对象的思想编写程序描述动物

题目&#xff1a; 使用面向对象的思想编写程序描述动物&#xff0c;说明&#xff1a; &#xff08;1) 分析兔子和青蛙的共性&#xff0c;定义抽象的动物类&#xff0c;拥有一些动物共有的属性&#xff1a;名字、颜色、类别&#xff08;哺乳类、非哺乳类&#xff09;&#xff0c…

20分钟拥有自己的ChatGPT4,高效低成本,小白必看

准备工作 1、准备一个3.5的账号 2、一张虚拟卡 开始步骤 从ChatGPT第一版发布到现在&#xff0c;还不到一年的时间中&#xff0c;可是它使用的GPT架构已经从3.5版本进化到现在的4.0版本&#xff0c;随之而来的是其能力的极大提升。下面是GPT-4在其官网的介绍中的一句话&…

conda环境下 ERROR: CMake must be installed to build dlib问题解决

1 问题描述 pip install -r requirements.txt 在构建video_retalking项目过程中&#xff0c;使用命令安装依赖包时&#xff0c;出现如下错误&#xff1a; Building wheels for collected packages: face-alignment, dlib, ffmpy, futureBuilding wheel for face-alignment …

与中通支付对接

最近项目接入商户&#xff0c;商户需要同步给中通支付&#xff0c;报错两个异常已解决。 一、json报错 未接入中通SKD之前&#xff0c;不会报错&#xff0c;接入后&#xff0c;json转换异常。 排查后发现&#xff0c;中通的jar包里JSON版本太低&#xff0c;与自身项目的版本冲…

不会写代码也能做自动化?推荐一款自动化测试神器

在软件测试这条道路上&#xff0c;大部分的职业技能发展道路都会是纯业务手工测试→自动化测试→性能测试→安全测试/测试开发。 但是却有着一部分人起初进入软件测试这一行看重的就是软件测试属于IT行业&#xff0c;门槛比较低&#xff0c;不需要代码基础。 这就导致了这一部…

0基础学java-day9

一、房屋出租系统-需求&&界面 1项目需求说明 实现基于文本界面的《房屋出租软件》。 能够实现对房屋信息的添加、修改和删除&#xff08;用数组实现&#xff09;&#xff0c;并能够打印房屋明细表 2 房屋出租系统-界面 2.1 项目界面 - 主菜单 2.2项目界面- 新增房…

Linux编写Shell命令脚本

1.编写Shell脚本 可以将Shell终端解释器当作人与计算机硬件之间的“翻译官”&#xff0c;它作为用户与Linux系统内部的通信媒介&#xff0c;除了能够支持各种变量与参数外&#xff0c;还提供了诸如循环、分支等高级编程语言才有的控制结构特性。要想正确使用Shell中的这些功能…

git的创建以及使用

1、上传本地仓库 首先确定项目根目录中没有.git文件&#xff0c;有的话就删了&#xff0c;没有就下一步。在终端中输入git init命令。注意必须是根目录&#xff01; 将代码存到暂存区 将代码保存到本地仓库 2、创建git仓库 仓库名称和路径&#xff08;name&#xff09;随便写…

vscode 里怎么自动提示 webpack 配置项?

webpack 的配置项非常多&#xff0c;容易忘记&#xff0c;能自动提示很有用&#xff0c;就是在配置文件里面添加下面代码 // 下面这行用于 vscode 中智能化自动提示 webpack 配置项 /** type {import(webpack).Configuration} */

文本三剑客之sed

一、sed编辑器 ■ sed是一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的—组规则来编辑数据流 ■ sed编辑器可以根据命令来处理数据流中的数据&#xff0c;这些命令要么从命令行中输入&#xff0c;要么存储在一个命令文本文件中 1、sed的工作流程主要…

分享一个适用于 Vue3 的好的组件库,PrimeVue组件。

一、PrimeVue介绍 PrimeVue 是一个基于 Vue.js 的 UI 组件库&#xff0c;专注于提供丰富、灵活、现代的 UI 组件&#xff0c;以帮助开发者构建功能强大的 Web 应用程序。PrimeVue 提供了一系列的组件&#xff0c;涵盖了从基本的表单元素到高级的数据表格和图表等各种组件。 二、…