When I'm trying to make my app, I stumbled upon this unexpected behavior where when I re-display a new QPixmap
in a QLabel
. I tried to simplify the code and ended up with the code below. I also attached the video of the behavior.
I provided here a replicable example (It just needs some .jpg file in the same directory):
import sys
import os
import random
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLabel, QSizePolicy
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
class AppDemo(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(200, 200, 400, 400)
current_working_dir = os.path.abspath('')
dir_files = os.listdir(current_working_dir)
# Saving .jpg from the dir
self.picture = []
for file in dir_files:
if file.endswith(".jpg"):
self.picture.append(file)
self.label = QLabel()
self.label.setStyleSheet("border: 1px solid black;") # <- for the debugging
self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)
self.label.setPixmap(self.random_picture_selector())
button = QPushButton("Reload Picture")
button.clicked.connect(self.reload_picture)
layout = QVBoxLayout(self)
layout.addWidget(button)
layout.addWidget(self.label)
def reload_picture(self):
self.label.setPixmap(self.random_picture_selector())
def random_picture_selector(self):
rnd_picture = random.choice(self.picture)
pixmap = QPixmap(rnd_picture)
pixmap = pixmap.scaledToWidth(self.label.width(), Qt.SmoothTransformation)
# pixmap = pixmap.scaled(self.label.width(), self.label.height(), Qt.KeepAspectRatio) # <- even this is not working
return pixmap
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = AppDemo()
demo.show()
sys.exit(app.exec_())
Additional Infos:
When simplifying the code I realized that the problem disappears when I removed these following lines. (although I'm not very sure that these part of the code really causes the problem)
pixmap = pixmap.scaledToWidth(self.label.width(), Qt.SmoothTransformation)
# pixmap = pixmap.scaled(self.label.width(), self.label.height(), Qt.KeepAspectRatio) # <- even this is not working
I really have no idea what causes the problem even after looking for the Docs of QPixmap
and QLabel
.
The problem is caused by the stylesheet border. If you just print the pixmap and label size after setting the pixmap, you'll see that the label width is increased by 2 pixels, which is the sum of the left and right border.
You either remove the border, or you use the contentsRect()
:
width = self.label.contentsRect().width()
pixmap = pixmap.scaledToWidth(width, Qt.SmoothTransformation)
Read more about the Box Model in the Qt style sheet documentation.