【PyQt】(自定义类)阴影遮罩

写了一个感觉有些用的小玩具。
用于给控件添加阴影遮罩(强调主控件的同时屏蔽其余控件的点击)



自定义阴影遮罩Mask:

from PyQt5.QtCore import QPoint,QRect,Qt,QPoint,QSize
from PyQt5.QtWidgets import QWidget,QLabel,QPushButton,QVBoxLayout
from PyQt5.QtGui import QColor,QPainter,QBitmap

class Mask(QWidget):
    __exclude=None
    __color=None
    def __init__(self,parent=None,*exclude,color=QColor(0,0,0,128)):
        super().__init__(parent)
        self.__exclude=set(exclude)
        self.__color=color
        self.show()
    def paintEvent(self,event):
        self.resize(self.parent().size())

        bit=QBitmap(self.size())
        bit.fill(Qt.black)
        painter_bit=QPainter(bit)
        for wid,offset in self.__Get_Offset().items():
            painter_bit.eraseRect(QRect(offset,wid.size()))
        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 widget in self.__exclude:
            if(not widget.isVisible()):
                continue
            wid=widget
            parent_wid=wid.parent()
            offset=QPoint(0,0)
            while (True):
                offset+=wid.pos()
                if(not parent_wid):
                    break
                if(parent_wid==parent_self):
                    break
                wid=wid.parent()
                parent_wid=wid.parent()
            if(parent_wid):
                record[widget]=offset
        return record

测试代码+运行结果:

import sys
from PyQt5.QtWidgets import QApplication
if __name__=='__main__':
    app = QApplication(sys.argv)

    lb_1=QPushButton("ABCDE")
    lb_1.setStyleSheet("font-size:150px ; background-color:#FFFF00")

    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:#00FFFF")

    win=QWidget()
    vbox=QVBoxLayout(win)
    vbox.addWidget(lb_1)
    vbox.addStretch(1)
    vbox.addWidget(lb_2)
    win.show()
    win.resize(800,400)

    # msk=Mask(win,lb_1,color=QColor(0,0,0,192))
    # 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(lb_2,lb_1,lb_3,color=QColor(0,0,0,192))
    # msk.setParent(None)

    sys.exit(app.exec())

【PyQt】(自定义类)阴影遮罩_第1张图片



说明:

  1. 即用即贴
  2. 这个Mask是个牛皮癣(因为设置了parent),需要撤走遮罩时仅需执行语句msk.setParent(None)
  3. 遮罩是规则的矩形。使用样式表实现的圆角按钮的遮盖效果并不理想,可以看到按钮四角出现留白没有遮盖的问题:
    【PyQt】(自定义类)阴影遮罩_第2张图片


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

你可能感兴趣的:(pyqt)