如何缩放 QPixmap 保留纵横比和居中图像?

How to scale a QPixmap preserving aspect and centering the image?

我想在 QMdiArea 中使用图像(svg 文件)作为背景。我将图像加载为 QPixmap,并使用

在 resizeEvent 方法中将其缩放到 QMdiArea 的大小
self._background_scaled = self._background.scaled(self.size(), QtCore.Qt.KeepAspectRatio)
self.setBackground(self._background_scaled)

但这会将图像放在左上角并在 X 或 Y 中重复它。我希望图像居中。

如何缩放 QPixmap 以调整其大小以保持纵横比,然后添加边框以获得准确的大小?

setBackground() 方法接受基于您传递给它的 QPixmap 构建的 QBrush,但是如果 QBrush 是基于 QPixmap 构建的,它将创建纹理(重复元素)并且没有办法改变这种行为。所以解决方法是重写paintEvent方法,直接绘制QPixmap:

import sys

from PySide2 import QtCore, QtGui, QtWidgets


def create_pixmap(size):
    pixmap = QtGui.QPixmap(size)
    pixmap.fill(QtCore.Qt.red)
    painter = QtGui.QPainter(pixmap)
    painter.setBrush(QtCore.Qt.blue)
    painter.drawEllipse(pixmap.rect())
    return pixmap


class MdiArea(QtWidgets.QMdiArea):
    def __init__(self, parent=None):
        super().__init__(parent)
        pixmap = QtGui.QPixmap(100, 100)
        pixmap.fill(QtGui.QColor("transparent"))
        self._background = pixmap

    @property
    def background(self):
        return self._background

    @background.setter
    def background(self, background):
        self._background = background
        self.update()

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QtGui.QPainter(self.viewport())
        background_scaled = self.background.scaled(
            self.size(), QtCore.Qt.KeepAspectRatio
        )
        background_scaled_rect = background_scaled.rect()
        background_scaled_rect.moveCenter(self.rect().center())
        painter.drawPixmap(background_scaled_rect.topLeft(), background_scaled)


if __name__ == "__main__":

    app = QtWidgets.QApplication(sys.argv)

    mdiarea = MdiArea()
    mdiarea.show()

    mdiarea.background = create_pixmap(QtCore.QSize(100, 100))

    sys.exit(app.exec_())