为QSE使用遮罩

2024-06-02 06:25:25 发布

您现在位置:Python中文网/ 问答频道 /正文

上下文

我有一个自定义的箭头小部件,它是透明的,但是它也有一个QGraphicsShadowEffect集。因为小部件是透明的,所以阴影可以通过小部件本身看到,这是不需要的,因为它会使小部件的颜色变暗。你知道吗

可能的途径

我对^{}函数和^{}函数做了一些研究。据我所知,setMask函数确实屏蔽了小部件的某些部分,而不是剪裁,这设置了画家不会绘制的区域(对我来说感觉相当)。你知道吗

有没有可能只在QGraphicsShadowEffect上应用掩码,以便只显示小部件区域外的阴影?你知道吗

兆瓦

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class ArrowWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.widgetSize = 500
        self.resize(self.widgetSize, self.widgetSize)
        self.circleRadius = self.widgetSize / 2
        self.blurRadius = 10

        self.circleRadius = self.widgetSize/2
        self.arrowHeight = self.circleRadius*(2/3)
        self.arrowWidth = self.circleRadius*(2/7)

        self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=self.blurRadius, xOffset=0, yOffset=0)
        self.setGraphicsEffect(self.shadow)
        self.graphicsEffect().setEnabled(True)

        self.borderPen = self.normalPen = QtGui.QPen(QtGui.QColor("#E7E7E7"), 1)
        self.centerPen = QtGui.QPen(QtGui.QColor("#7F7F7F"), self.widgetSize/14)
        self.centerHoverPen = QtGui.QPen(QtGui.QColor("#2F2F2F"), self.widgetSize/14)

        self.currentBrush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 200))
        self.currentPen = self.centerPen

        self.region = QtGui.QRegion(self.rect(), QtGui.QRegion.Ellipse)
        self.setMask(self.region)


    def mousePressEvent(self, event):
        if event.buttons() == QtCore.Qt.LeftButton:
            self.mousePos = event.pos()

    def mouseMoveEvent(self, event):
        if event.buttons() == QtCore.Qt.LeftButton:
            self.move(self.pos() + event.pos() - self.mousePos)

    def enterEvent(self, event):
        self.currentPen = self.centerHoverPen
        self.setCursor(QtCore.Qt.PointingHandCursor)
        self.update()

    def leaveEvent(self, event):
        self.currentPen = self.centerPen
        self.setCursor(QtCore.Qt.ArrowCursor)
        self.update()

    def drawArrow(self, qp, rect):
        qp.setPen(self.currentPen)

        qp.drawLine(rect.center() + QtCore.QPoint(self.arrowWidth / 2, self.arrowHeight / 2),
                    rect.center() + QtCore.QPoint(-self.arrowWidth / 2, 0))

        qp.drawLine(rect.center() + QtCore.QPoint(-self.arrowWidth / 2, 0),
                    rect.center() + QtCore.QPoint(self.arrowWidth / 2, -self.arrowHeight / 2))

    def paintEvent(self, event):
        qp = QtGui.QPainter(self)
        qp.setRenderHints(qp.Antialiasing)
        qp.translate(.5, .5)  # QPainter isn't pixel based. Doing that for better results.
        rect = self.rect().adjusted(0, 0, -1, -1)
        qp.setPen(self.borderPen)
        qp.setBrush(self.currentBrush)
        qp.drawEllipse(self.rect().center(), self.circleRadius, self.circleRadius)
        self.drawArrow(qp, rect)


class MainWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QGridLayout()
        self.setLayout(layout)
        self.frame = QtWidgets.QFrame()
        self.frame.setFrameShape(self.frame.StyledPanel|self.frame.Raised)
        self.frame.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        layout.addWidget(self.frame, 0, 0, 1, 2)
        self.button = QtWidgets.QPushButton('button')
        layout.addWidget(self.button, 0, 0)

        self.label = QtWidgets.QLabel('label')
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(self.label, 0, 1)

        self.resize(600, 600)
        self.arrowWidget = ArrowWidget(self)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    testWidget = MainWidget()
    testWidget.show()
    sys.exit(app.exec_())

Tags: rectselfevent部件defqtframecenter