I have a bunch of layouts and I'm trying to display two differently sized square images next to each other. My ImageLabel class should watch for file changes (when the image at the specific path is overwritten) and update/refresh the image(s) accordingly.
When the application starts, the images are displayed correctly but when one (or more) image file is updated the pixmap returns QPixmap::scaled: Pixmap is a null pixmap
.
...
class Ui_MainWindow(QMainWindow):
...
# Set image and QR code based on path and size
self.image_label.set_image(IMAGE_PATH, 500)
...
self.qr_label.set_image(QR_PATH, 200)
...
# Create a QLabel that shows an image and watches for file changes.
# When a new image is generated, refresh the displayed image.
class ImageLabel(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.watcher = QFileSystemWatcher()
self.watcher.fileChanged.connect(self.refresh_image)
self.setAlignment(Qt.AlignCenter)
def set_image(self, image_path, width):
self.image_path = image_path
self.watcher.addPath(image_path)
self.refresh_image(width)
def refresh_image(self, width):
pixmap = QPixmap(self.image_path)
self.setPixmap(pixmap.scaled(width, width, Qt.KeepAspectRatio, Qt.SmoothTransformation))
...
I'm sure it worked before when I only needed to update one image.
I tried adding a timer to make sure the background process is finished before refreshing but it did not help.
Maybe I need an entirely different approach - one that adds a file watcher to each file individually or something?
UPDATE: I tried to isolate it and the following code works as expected. It just doesn't work in context of the rest of my GUI. Must be some other issue then. Oops.
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QFileSystemWatcher, Qt
# Constants
IMAGE_PATH = "image.png"
QR_PATH = "qr.png"
# The main UI of the appication
class Ui_MainWindow(QMainWindow):
# Setup the UI
def setup_ui(self, MainWindow):
self.central_widget = QtWidgets.QWidget(MainWindow)
self.main_layout = QtWidgets.QHBoxLayout(self.central_widget)
# Create image label
self.image_label = ImageLabel()
self.image_label.setObjectName("imageLabel")
# Create QR label
self.qr_label = ImageLabel()
self.qr_label.setObjectName("qr_label")
# Set image and QR code
self.image_label.set_image(IMAGE_PATH, 500)
self.qr_label.set_image(QR_PATH, 200)
self.main_layout.addWidget(self.image_label)
self.main_layout.addWidget(self.qr_label)
MainWindow.setCentralWidget(self.central_widget)
# Create a QLabel that shows an image and watches for file changes.
# When a new image is generated, refresh the displayed image.
class ImageLabel(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.watcher = QFileSystemWatcher()
self.watcher.fileChanged.connect(self.refresh_image)
self.setAlignment(Qt.AlignCenter)
def set_image(self, image_path, width):
self.image_path = image_path
self.watcher.addPath(image_path)
self.width = width
self.refresh_image()
def refresh_image(self):
pixmap = QPixmap(self.image_path)
self.setPixmap(pixmap.scaled(self.width, self.width, Qt.KeepAspectRatio, Qt.SmoothTransformation))
# Setup the main window and application
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
# Setup main window
ui = Ui_MainWindow()
ui.setup_ui(MainWindow)
MainWindow.show()
sys.exit(app.exec_())