Инклюзивные QLabels с изменением размеров QPixmaps в горизонтальном макете, сохраняя пропорции изображений - PullRequest
0 голосов
/ 01 марта 2019

Я пытаюсь создать редактор изображений, используя PyQt5.

Я субклассировал QLabel, чтобы создать метку, которая отображает изображение через setPixmap.Класс гарантирует, что при каждом изменении размера метки изображение сохраняет пропорции.

Я поместил 2 из этих меток в горизонтальный макет и установил для их растровых изображений 2 изображения.

Все прекрасно работает, за исключением случаев, когда размер окна изменяется определенным образом.

Когда я начинаю увеличивать ширину окна, все прекрасно работает.Но когда я начинаю уменьшать его, первая этикетка начинает уменьшаться, а вторая остается такой же .Первая этикетка продолжает уменьшаться, пока она больше не может уменьшаться в размере, заставляя вторую уменьшаться.

Это не то, что я хочу.Я хочу, чтобы обе метки оставались одинаковыми , пока размер окна изменяется.Как я могу это сделать?

Вот минимальная часть моего кода, чтобы воспроизвести мою проблему:

import sys

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QPixmap

class ImageLabel(QtWidgets.QLabel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setMinimumSize(1,1)
        self.setScaledContents(False)

        self.pixmap = QPixmap(1, 1)

    def set_image(self, image_path):
        pixmap = QPixmap(image_path)
        self.set_pixmap(pixmap)

    def set_pixmap(self, pixmap):
        self.pixmap = pixmap
        self.setPixmap(pixmap)

    def resizeEvent(self, event):
        self.setPixmap(self.scaled_pixmap())

    def scaled_pixmap(self):
        return self.pixmap.scaled(
            self.size(),
            Qt.KeepAspectRatio,
            Qt.SmoothTransformation
        )

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi()
        self.start()

    def setupUi(self):
        self.setWindowTitle('Image Editor')

        self.centralWidget = QtWidgets.QWidget()

        self.hlayout = QtWidgets.QHBoxLayout()

        self.image_1 = ImageLabel()
        self.hlayout.addWidget(self.image_1)

        self.image_2 = ImageLabel()
        self.hlayout.addWidget(self.image_2)

        self.centralWidget.setLayout(self.hlayout)
        self.setCentralWidget(self.centralWidget)

        self.resize(800, 600)

    def start(self):
        self.image_1.set_image(
            r"orig.jpg"
        )

        self.image_2.set_image(
            r"edit.jpg"
        )

app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()

mainWindow.show()
exitCode = app.exec_()

sys.exit(exitCode)

1 Ответ

0 голосов
/ 01 марта 2019

Вместо использования QLabel проще всего использовать QGraphicsView с QGraphicsPixmapItem:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class ImageLabel(QtWidgets.QGraphicsView):
    def __init__(self, *args, **kwargs):
        super(ImageLabel, self).__init__(*args, **kwargs)
        self.setScene(QtWidgets.QGraphicsScene())
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

    def setImage(self, filename):
        self.setPixmap(QtGui.QPixmap(filename))

    def setPixmap(self, pixmap):
        item = QtWidgets.QGraphicsPixmapItem(pixmap)
        item.setTransformationMode(QtCore.Qt.SmoothTransformation)
        self.scene().addItem(item)

    def resizeEvent(self, event):
        r = self.scene().itemsBoundingRect()
        self.fitInView(r, QtCore.Qt.KeepAspectRatio)
        super(ImageLabel, self).resizeEvent(event)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi()
        self.start()

    def setupUi(self):
        self.setWindowTitle('Image Editor')

        self.image_1 = ImageLabel()
        self.image_2 = ImageLabel()

        self.centralWidget = QtWidgets.QWidget()
        self.setCentralWidget(self.centralWidget)

        hlayout = QtWidgets.QHBoxLayout(self.centralWidget)
        hlayout.addWidget(self.image_1)
        hlayout.addWidget(self.image_2)

        self.resize(800, 600)

    def start(self):
        self.image_1.setImage(
            r"orig.jpg"
        )

        self.image_2.setImage(
            r"edit.jpg"
        )

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()

    mainWindow.show()
    exitCode = app.exec_()

    sys.exit(exitCode)
...