【问题标题】:QMovie with border radius带边框半径的 QMovie
【发布时间】:2023-04-07 03:22:02
【问题描述】:

如何在 PyQt5 中使用 QMovie 应用边框半径或以其他方式实现圆角效果?它似乎对 QSS 没有反应。尽管我不认为它是相关的,但无论如何,这是我当前的代码,以说明我尝试过的内容:

image = QLabel()
image.setObjectName("rant-image")
movie = QMovie("image_cache/" + img_name)
image.setMovie(movie)
movie.start()

使用 QSS:

QLabel#rant-image{
    border-radius: 5px;
}

我还尝试通过子类化 QWidget 来绘制每个paintEvent 的当前像素图,但没有出现任何内容,并且像素图的尺寸为 0:

invisible_pen = QPen()
invisible_pen.setWidth(0)
invisible_pen.setStyle(Qt.NoPen)


class RoundedMovie(QWidget):

    def __init__(self, movie, parent=None):
        QWidget.__init__(self, parent)
        self.movie = movie

    def setMovie(self, movie):
        self.movie = movie

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)
        pixmap = self.movie.currentPixmap()
        brush = QBrush(pixmap)
        rect = QRect(0, 0, pixmap.width() - 10, pixmap.height() - 10)
        painter.setPen(invisible_pen)
        painter.setBrush(brush)
        painter.drawRoundedRect(rect, 5, 5)

我也知道上面的实现是行不通的,因为 paintEvent 的发生频率不足以按预期播放电影

【问题讨论】:

    标签: python pyqt pyqt5 gif qmovie


    【解决方案1】:

    一个可能的解决方案是实现QProxyStyle:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class RoundPixmapStyle(QtWidgets.QProxyStyle):
        def __init__(self, radius=10, *args, **kwargs):
            super(RoundPixmapStyle, self).__init__(*args, **kwargs)
            self._radius = radius
    
        def drawItemPixmap(self, painter, rectangle, alignment, pixmap):
            painter.save()
            pix = QtGui.QPixmap(pixmap.size())
            pix.fill(QtCore.Qt.transparent)
            p = QtGui.QPainter(pix)
            p.setBrush(QtGui.QBrush(pixmap))
            p.setPen(QtCore.Qt.NoPen)
            p.drawRoundedRect(pixmap.rect(), self._radius, self._radius)
            p.end()
            super(RoundPixmapStyle, self).drawItemPixmap(painter, rectangle, alignment, pix)
            painter.restore()
    
    if __name__ == '__main__':
        import sys 
        app = QtWidgets.QApplication(sys.argv)
        w = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        proxy_style = RoundPixmapStyle(radius=20, style=w.style())
        w.setStyle(proxy_style)
        movie = QtGui.QMovie("foo.gif")
        w.setMovie(movie)
        movie.start()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 如何实现最小宽度?
    • @AlgoRythm 最小宽度是什么意思?这些属性必须在 QLabel 中建立
    • 如果我为 QLabel 设置了一个比 gif 大的固定大小,则 gif 将绘制在左中部,周围有空格。
    • @AlgoRythm 使用 w = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter, scaledContents=True)
    • @AlgoRythm 在p = QtGui.QPainter(pix) 之后添加p.setRenderHint(QtGui.QPainter.Antialiasing)
    猜你喜欢
    • 2020-09-15
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2011-07-19
    • 1970-01-01
    相关资源
    最近更新 更多