Пропорциональное изменение размера QMovie

Собственно. Нужно подгонять размеры гифки под размеры лэйбла. В случае с изображением я использую setScaledToWidth, но аналога для гифок не нашел, поэтому накидал вот какой способ. Однако в некоторых случаях он изменяет размер непропорционально, особенно, когда ширина больше высоты.

На скрине ниже показан пример изображения и как он располагается в моём лэйбле. введите сюда описание изображения

from PyQt5 import QtWidgets,  QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QMovie
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QLabel, QVBoxLayout, QScrollArea
from PIL import Image

class MyWin(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self.background = QLabel(self)
        background_pixmap = QPixmap('background.png')
        self.background.resize(background_pixmap.width() - 30, background_pixmap.height() - 100)
        self.background.setStyleSheet('background-color: black')
        self.background.setPixmap(background_pixmap)

        movie = QMovie('mov.gif')
        self.background.setMovie(movie)

        im = Image.open('mov.gif')
        gif_size = (width, height) = im.size
        if gif_size[0] > self.background.width():
            _gif_w = gif_size[0]
            _gif_h = gif_size[1]
            while _gif_w > self.background.width():
                _gif_w = _gif_w - 1
                _gif_h = _gif_h - 1
                print(_gif_w, _gif_h)
            movie.setScaledSize(QtCore.QSize(_gif_w, _gif_h))
            movie.start()
        else:
            movie.start()

        self.resize(background_pixmap.width(), background_pixmap.height())

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

Ответы (1 шт):

Автор решения: S. Nick

Sorry, я не понял что вы под что подгоняете, но предложу вам попробовать пример:

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.setRenderHint(QtGui.QPainter.Antialiasing) 

        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)
    w = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter, scaledContents=True)

    proxy_style = RoundPixmapStyle(radius=20, style=w.style())
    w.setStyle(proxy_style)
    movie = QtGui.QMovie("D:/_Qt/__Qt/892768447/QLabel/Data/foo.gif")
    w.setMovie(movie)
    movie.start()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения


Update

Я все равно не понял, что вы хотите. Вам надо показать ОДНО изображение (а не ТРИ) что вы хотите получит и ОДНО изображение - что у вас получается.

И попробуйте другой вариант вашего примера:

убрал:

self.background = QLabel(self)    

добавил:

self.background = QtWidgets.QLabel(self, 
    alignment=QtCore.Qt.AlignCenter, 
    scaledContents=True)

from PyQt5 import QtWidgets,  QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QMovie
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QLabel, QVBoxLayout, QScrollArea
from PIL import Image


class MyWin(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()

#        self.background = QLabel(self)                                                                # ---
        self.background = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter, scaledContents=True) # +++

        background_pixmap = QPixmap('background.png')
        self.background.resize(background_pixmap.width() - 30, background_pixmap.height() - 100)
        self.background.setStyleSheet('background-color: black')
        self.background.setPixmap(background_pixmap)

        movie = QMovie('D:/_Qt/__Qt/892768447/QLabel/Data/foo.gif')                 # mov.gif
        self.background.setMovie(movie)
        im = Image.open('D:/_Qt/__Qt/892768447/QLabel/Data/foo.gif')                # mov.gif
        gif_size = (width, height) = im.size

        if gif_size[0] > self.background.width():
            _gif_w = gif_size[0]
            _gif_h = gif_size[1]
            while _gif_w > self.background.width():
                _gif_w = _gif_w - 1
                _gif_h = _gif_h - 1
                print(_gif_w, _gif_h)
            movie.setScaledSize(QtCore.QSize(_gif_w, _gif_h))
            movie.start()
        else:
            movie.start()

        self.resize(background_pixmap.width(), background_pixmap.height())

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MyWin()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения


Update 2

Я вам предложу еще один вариант (последний):

from PyQt5 import QtWidgets,  QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QMovie
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QLabel, QVBoxLayout, QScrollArea
from PIL import Image


class MyWin(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        #                                                  mov.gif
        im = Image.open('D:/_Qt/__Qt/892768447/QLabel/Data/foo.gif')             # +++ !!!
        w, h = im.size                                                           # +++

#-        self.background = QLabel(self)                                                               # ---
        self.background = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter, scaledContents=True) # +++

#1        background_pixmap = QPixmap('button1.png')            # +
        background_pixmap = QPixmap('150_600.png')              # +  

        w2, h2 = background_pixmap.width(), background_pixmap.height()            # +++

        if int(w2/h2*100) < int(w/h*100):                                         # +++ !!!
            w_new = w2
            h_new = int(w2*h/w)  
        else:
            h_new = h2
            w_new = int(h2*w/h)

#=        self.background.resize(background_pixmap.width() - 30, background_pixmap.height() - 100) # ---
        self.background.resize(w_new, h_new)                                                       # +++ !!!

        self.background.setStyleSheet('background-color: black')
        self.background.setPixmap(background_pixmap)

        movie = QMovie('D:/_Qt/__Qt/892768447/QLabel/Data/foo.gif')                 # mov.gif
        self.background.setMovie(movie)
        im = Image.open('D:/_Qt/__Qt/892768447/QLabel/Data/foo.gif')                # mov.gif

        '''
        gif_size = (width, height) = im.size
        if gif_size[0] > self.background.width():
            _gif_w = gif_size[0]
            _gif_h = gif_size[1]
            while _gif_w > self.background.width():
                _gif_w = _gif_w - 1
                _gif_h = _gif_h - 1
                print(_gif_w, _gif_h)
            movie.setScaledSize(QtCore.QSize(_gif_w, _gif_h))
            movie.start()
        else:
            movie.start()
        '''

        movie.start()

        self.resize(background_pixmap.width(), background_pixmap.height())

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MyWin()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка