Search code examples
pythonpyqtpyqt6

How to extract image content of QLabel using PyQt6?


I'm new to PyQt and GUI design. I have a very basic GUI with two QLabels and a push button. One QLabel displays live footage from an USB camera. I want to make it so that on pressing the button, the second QLabel displays the current frame from the first QLabel (effectively taking a photo). How do I access the current "value" or content of a QLabel?

I can't seem to be able to find an answer to this. Could it be the case that QLabel doesn't actually "store" any data?

EDIT: Apologies for the initial lack of technical details. I wasn't sure what would be helpful.

What I'm doing is creating a QThread class to handle the live capture of the camera and I send the current live frame as an ndarray pyqtSignal to the main thread. Then I convert it from grayscale to the pixmap format required for display on the QLabel.

This is the code for the camera:

```python

class BaslerCamera(QThread):
    change_pixmap_signal = pyqtSignal(np.ndarray)

    def __init__(self):
        super().__init__()
        self.run_flag = True

    def run(self):
    
        #Creates transport layer instance
        #This is an abstraction of the physical connection between 
        #the PC and the camera
        tl_factory = pylon.TlFactory.GetInstance()
    
        #Lists all available devices
        devices = tl_factory.EnumerateDevices()
        print("List of connected cameras:")
        for device in devices:
            print(device.GetFriendlyName())
    
        #Creates camera object to simplify the work with the camera
        camera = pylon.InstantCamera()
    
        #Attaches the first available camera to the camera object
        camera.Attach(tl_factory.CreateFirstDevice())
    
        #Connects the device and applies basic configuration
        camera.Open()
    
        #Sets the user selected exposure time of the camera in 
        #microseconds
        camera.ExposureTime.SetValue(30000)
    
        #Instructs camera to start grabbing frames using a specific 
        #strategy
        camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
    
        while camera.IsGrabbing() and self.run_flag:
        #Uses a timeout in miliseconds to check if there has been 
        #a result
        #from the grabbing. If there is no result, returns 
        #Exception 
            grabResult = camera.RetrieveResult(2000,
                                    
            pylon.TimeoutHandling_ThrowException)
        
            if grabResult.GrabSucceeded():
                #img is a numpy array
                camera_img = grabResult.GetArray()
                self.change_pixmap_signal.emit(camera_img)
    
            grabResult.Release()
    
        print("Closing Camera")
        camera.StopGrabbing()
        camera.Close()

    def stop(self):
        self.run_flag = False
        self.wait()

`Here is the part of the code for the communication with the main thread:`

    self.camera_thread = BaslerCamera()
    self.camera_thread.change_pixmap_signal.connect(self.update_image)
    self.camera_thread.start()

`The functions for updating the image on the QLabel are:`

    def update_image(self, camera_img):
        #Updates continuous shot image
        qt_img = self.convert_basler_qt(camera_img)
        self.camera_label.setPixmap(qt_img)

    def convert_basler_qt(self,camera_img):
        h, w = camera_img.shape
        bytes_per_line = w
        convert_to_Qt_format = QtGui.QImage(camera_img.data,                               
        w,h,bytes_per_line,                               
        QtGui.QImage.Format.Format_Grayscale8)
        p = Convert_to_Qt_format.scaled(600,400,
            Qt.AspectRatioMode.KeepAspectRatio)
        return QPixmap.fromImage(p)

Solution

  • As indicated by @musicamante, I can call the pixmap() method on my first QLabel and assign the return to the second QLabel.