在保持图像纵横比的同时,水平布局内具有 Pixmap 调整大小行为的标签不一致
Incosistent QLabels with QPixmaps resizing behavior inside horizontal layout while keeping aspect ratio of images
我正在尝试使用 PyQt5 创建图像编辑器。
我子classed QLabel
创建了一个通过setPixmap
显示图像的标签。 class 确保无论何时调整标签大小时,图像都保持纵横比。
我将其中的 2 个标签放在水平布局中,并将它们的像素图设置为 2 个图像。
一切都很好,除了 window 以某些方式调整大小时。
当我开始增加 window 的宽度时,一切正常。但是当我开始缩小它时,第一个标签开始缩小,而 第二个保持不变。第一个标签不断缩小,直到它不能再缩小,迫使第二个标签缩小。
这不是我想要的。我希望 两个标签保持相同大小 而 window 被调整大小。我怎样才能做到这一点?
这里是我的代码的最小部分来重现我的问题:
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)
不使用 QLabel,最简单的方法是使用带有 QGraphicsPixmapItem 的 QGraphicsView:
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)
我正在尝试使用 PyQt5 创建图像编辑器。
我子classed QLabel
创建了一个通过setPixmap
显示图像的标签。 class 确保无论何时调整标签大小时,图像都保持纵横比。
我将其中的 2 个标签放在水平布局中,并将它们的像素图设置为 2 个图像。
一切都很好,除了 window 以某些方式调整大小时。
当我开始增加 window 的宽度时,一切正常。但是当我开始缩小它时,第一个标签开始缩小,而 第二个保持不变。第一个标签不断缩小,直到它不能再缩小,迫使第二个标签缩小。
这不是我想要的。我希望 两个标签保持相同大小 而 window 被调整大小。我怎样才能做到这一点?
这里是我的代码的最小部分来重现我的问题:
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)
不使用 QLabel,最简单的方法是使用带有 QGraphicsPixmapItem 的 QGraphicsView:
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)