In PyQt I'm trying to create a label which contains a pixmap and have the pixmap automatically resize as the label resizes — say, as a result of the window the label is in resizing.
I am experiencing several problems:
- The window refuses to resize smaller than its original size.
- If you resize the window to a larger size, you can never resize back to a smaller size.
- As the window resizes, the label also resizes correctly, but its pixmap does not repaint properly. It appears to "tear" or repeat pixels horizontally and/or vertically.
I started by creating a class PixmapLabel
that inherits from QLabel
since I wanted to override the resizeEvent
event:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
# You can plug in a path to an image of your choosing.
IMAGE_PATH = '../assets/launch_image.jpeg'
class PixmapLabel(QLabel):
"""
A label widget that has a pixmap. As the label resizes so does the
pixmap.
"""
def __init__(self, pixmap: QPixmap = None):
super().__init__()
self.setStyleSheet('background-color: lightgray')
self.setPixmap(pixmap)
def resizeEvent(self, event: QResizeEvent):
"""As the PixmapLabel resizes, resize its pixmap."""
super().resizeEvent(event)
self.setPixmap(self.pixmap())
def setPixmap(self, pixmap: QPixmap):
if pixmap is None:
return
# Resize the widget's pixmap to match the width of the widget preserving
# the aspect ratio.
width = self.width()
pixmap = pixmap.scaledToWidth(width)
super().setPixmap(pixmap)
Here is the code for the MainWindow
(which derives from QDialog
):
class MainWindow(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle('PyQt PixmapLabelWidget Test')
self.resize(300, 300)
# Set the window's main layout.
self.main_layout = QVBoxLayout()
self.setLayout(self.main_layout)
# Add a single widget — a PixmapLabel — to the main layout.
self.lbl_image = PixmapLabel()
self.main_layout.addWidget(self.lbl_image)
pixmap = QPixmap(IMAGE_PATH)
self.lbl_image.setPixmap(pixmap)
Finally, here's the code to run the Python app/script:
if __name__ == '__main__':
app = QApplication([])
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
Here's how the window initially renders with the label and its pixmap: https://cln.sh/gEldrO+.
Here's what it looks like after it has been resized: https://cln.sh/MuhknK+.
You should be able to see the "tearing."
Any suggestions about how to make this widget resize its pixmap correctly?