简体   繁体   English

pyqt 图像掩码不随图像移动

[英]pyqt image mask not moving with image

I'm trying to hide/show an image in PyQT using a mask.我正在尝试使用遮罩隐藏/显示 PyQT 中的图像。 I'm able to obtain a nice result with the following code:我可以使用以下代码获得一个不错的结果:

    self.picture = QLabel()
    self.pix = QPixmap('PyQt_Logo.png')
    self.picture.setPixmap(self.pix)
    self.picture.setMask(self.pix.createMaskFromColor(Qt.transparent, Qt.MaskOutColor))

But if I align the picture in the center of its layout container using:但是,如果我使用以下方法将图片对齐在其布局容器的中心:

    self.picture.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)

the mask is not moved and it is applied left-aligned.遮罩不会移动,它是左对齐应用的。 How to apply the image mask on the centered image?如何在居中的图像上应用图像蒙版?

The mask is always based in widget coordinates, but if you change the alignment of the image it won't translate the mask along with it.遮罩始终基于小部件坐标,但如果您更改图像的 alignment,它不会随之平移遮罩。

A possible solution is to install an event filter on the label and update the mask whenever it's resized.一种可能的解决方案是在 label 上安装事件过滤器,并在调整大小时更新掩码。 In order to do so, we need to keep a persistent reference of the mask, but using a QRegion (which allows translation):为此,我们需要保持对掩码的持久引用,但使用 QRegion(允许翻译):

        self.baseMask = QRegion(self.pix.createMaskFromColor(Qt.transparent, Qt.MaskOutColor))
        self.picture.setMask(self.baseMask)
        self.picture.installEventFilter(self)
        # ...

    def eventFilter(self, obj, event):
        if event.type() == QEvent.Type.Resize:
            rect = self.picture.pixmap().rect()
            rect.moveCenter(self.picture.rect().center())
            self.picture.setMask(self.baseMask.translated(rect.topLeft()))
        return super().eventFilter(obj, event)

Alternatively, with a subclass:或者,使用子类:

class MaskLabel(QLabel):
    baseMask = None
    def setMask(self, mask):
        if isinstance(mask, QBitmap):
            mask = QRegion(mask)
        self.baseMask = mask
        self.updateMask()

    def updateMask(self):
        if self.baseMask and self.pixmap():
            rect = self.pixmap().rect()
            rect.moveCenter(self.rect().center())
            super().setMask(self.baseMask.translated(rect.topLeft()))

    def resizeEvent(self, event):
        self.updateMask()

Obviously, the above is only valid for centered images, if you need a different alignment, you need to verify the alignment direction and eventually translate the mask accordingly, based on the label rect() .显然,以上仅对居中图像有效,如果您需要不同的 alignment,则需要验证 alignment 方向并最终根据 ZD304BA20E96D87411588EE rect()相应地平移掩码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM