Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Reload QLabel QImage



  • I honestly don't know if I'm doing something wrong or if I've stumbled across an internal memory issue.

    I have the below code which lets you open an image from a sequence into a QLabel. Once it's loaded, when you click on the image it reloads the QImage into the QLabel using a QPixmap. Eventually, using a QPainter object, I when clicking on the image to cycle through adding a few lines and then resetting back to the original image. It's slow to read the original image so I don't want to have to do that with every click. All that said, while it sometimes reloads properly for many clicks in a row, sometimes it becomes corrupted (becoming vertical lines, or all white other than a few speckles towards the top, or other such basic patterns). Also, it'll sometimes get progressively worse as you keep clicking but it never gets better without restarting the app.

    I can't predict when it's going to reload which way. Also, it rarely, but occasionally closes when you click with nothing but a "Process finished with exit code -1073741819 (0xC0000005)" message.

    Thoughts?

    Thanks

    import sys
    import time
    from pathlib import Path
    
    from brilliantimagery.sequence import Sequence
    import numpy as np
    from PySide2 import QtGui
    from PySide2.QtCore import QFile, QSettings, QSize, Qt, QPoint
    from PySide2.QtGui import QImage, QMouseEvent, QColor
    from PySide2.QtWidgets import QApplication, QMainWindow, QFileDialog
    
    from brilliantimagery_ui.gui_mainwindow import Ui_MainWindow
    
    
    class MainWindow(QMainWindow):
    
        def __init__(self):
            super(MainWindow, self).__init__()
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
            self.sequence = None
            self.image = None
    
            # Ramp Tab Setup
            self.ui.ramp_folder_button.clicked.connect(self.open_sequence)
    
        def open_sequence(self):
            folder = self.open_folder(self.ui.ramp_folder_edit,
                                      'E:\\Pictures\\Album\\Timelapse\\test\\dng')
            self.load_sequence(folder)
    
        def load_sequence(self, folder):
            if not folder or not Path(folder).is_dir():
                return
            if not self.sequence or folder != self.sequence.path:
                self.sequence = Sequence(folder)
                self.files_last_parsed = time.time()
    
            image = self.sequence.get_reference_image(index_order='yxc').astype(np.uint8)
            h, w, _ = image.shape
            image = np.reshape(image, (image.size, ))
            self.image = QImage(image, w, h, QImage.Format_RGB888)
    
            self.draw_image()
    
        def mouseReleaseEvent(self, event: QMouseEvent):
            if not self.image:
                return
    
            image_location = self.ui.ramp_image.mapToGlobal(QPoint(0, 0))
            image_x = image_location.x()
            image_y = image_location.y()
            image_width = self.image.width()
            image_height = self.image.height()
            x = event.globalX()
            y = event.globalY()
    
            if not (image_x <= x <= image_x + image_width and image_y <= y <= image_y + image_height):
                return
    
            self.draw_image()
    
        def draw_image(self):
            canvas = QtGui.QPixmap(self.image)
            self.ui.ramp_image.setPixmap(canvas)
    
        def open_folder(self, line_edit, start_location):
            folder = QFileDialog.getExistingDirectory(self, "Open Directory",
                                                      start_location)
            line_edit.setText(folder)
            return folder
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    
        window = MainWindow()
        window.show()
    
        sys.exit(app.exec_())
    
    

  • Moderators

    I don't know python that well, but isn't image a temporary variable? From QImage documentation:

    The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer.

    So if image goes out of scope and destroys the data your self.image is pointing to garbage, which sometimes happens to still hold the data, sometimes gets overwritten and you see garbage and sometimes it crashes your app.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    What version of PySide2 are you using ?
    How did you install it ?
    What version of Windows are you running ?


  • Moderators

    I don't know python that well, but isn't image a temporary variable? From QImage documentation:

    The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer.

    So if image goes out of scope and destroys the data your self.image is pointing to garbage, which sometimes happens to still hold the data, sometimes gets overwritten and you see garbage and sometimes it crashes your app.


Log in to reply