0

I have a problem. My PyQt5 application is crashing as i resize,drag,maximize window. Here's thread:

class ImageCapturer(QtCore.QThread):
     changeImages = QtCore.pyqtSignal(QtGui.QImage, QtGui.QImage)
     lower_hsv = numpy.array([0,0,0])
     upper_hsv = numpy.array([180,255,255])
     cap = cv2.VideoCapture(1)

     def run(self):
        while True:
            ret, frame = self.cap.read()
            if ret:
                original = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

                #Some modification to frame

                height, width, channel = original.shape
                qt_img = QtGui.QImage(original, width, height, original.strides[0], QtGui.QImage.Format_RGB888)

                height, width, channel = frame.shape
                qt_img2 = QtGui.QImage(frame, width, height, res.strides[0], QtGui.QImage.Format_RGB888)
                self.changeImages.emit(qt_img, qt_img2)

    self.cap.release()

Also here is the function that is connected with signal :

@pyqtSlot(QtGui.QImage,QtGui.QImage)
def setImages(self, original, frame):
     qt_pixmap = QtGui.QPixmap.fromImage(original)
     self.original_image.setPixmap(qt_pixmap)

     qt_pixmap = QtGui.QPixmap.fromImage(res)
     self.processed_image.setPixmap(qt_pixmap)

Heres code of labels :

    self.original_image = QtWidgets.QLabel()
    self.original_image.setStyleSheet('border : 1px solid gray')
    self.original_image.setMinimumHeight(240)
    self.original_image.setMinimumWidth(320)
    self.original_image.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
    self.original_image.setScaledContents(True)

    self.processed_image = QtWidgets.QLabel()
    self.processed_image.setStyleSheet('border : 1px solid gray')
    self.processed_image.setMinimumHeight(240)
    self.processed_image.setMinimumWidth(320)
    self.processed_image.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
    self.processed_image.setScaledContents(True)

Heres how i created instance of that thread :

    self.getImagesThread = ImageCapturer(self)
    self.getImagesThread.changeImages.connect(self.setImages)
    self.getImagesThread.setTerminationEnabled(True)

Also i created this based of : PyQt showing video stream from opencv

It doesn't happen all the time but it does at most of it. Sometimes i can resize maximize and all that.. Also I don't get any exception message or anything.. since i run it from IDLE once it happens it just shows ">>>" and that is basically it. Does anyone have a solution? I am new into this kind of stuff... Also it works normally when i use self.msleep(500) lets say.. but whats the point of that when i want it to be smooth and i want it as video..

  • Interstingly enought it works on my linux!!!?!?!?!? What the hell is going on –  Dec 03 '18 at 21:54
  • I also have version with QTimer that one works at both platforms but QTimer can block the main thread which can be annoying so... –  Dec 03 '18 at 21:55
  • Also it works fine when i comment out this line #self.changeImages.emit(qt_img, qt_img2) but i need that line!.. –  Dec 04 '18 at 07:05
  • Also it doesnt crash when i comment this out self.original_image.setPixmap(QtGui.QPixmap.fromImage(original)) self.processed_image.setPixmap(QtGui.QPixmap.fromImage(res)) –  Dec 04 '18 at 08:04
  • Just tested some stuff so i can give you more details.. if someone has solution please tell me! –  Dec 04 '18 at 08:05
  • It usually happens as SOON as i drag it or even click it by title bar.. not on linux tho –  Dec 04 '18 at 08:15
  • if you want help you must provide a [mcve], if you do not know what it is then read the link – eyllanesc Dec 04 '18 at 08:17

1 Answers1

0

You can’t use threads and GUIs without extreme care. You can NOT manipulate GUI objects from anything but the main thread. If you want to offload work to a background thread, take care to deliver the results to the main thread via a queued Signal slot connection. See the Qt documentation about this - there are recipes in the threading documentation. Or take a look at this question: Background thread with QThread in PyQt

deets
  • 6,285
  • 29
  • 28
  • I think i used pyqtSignal up there and "connected" it with function.. I dont know if i did it properly tho... I think it is?.. Also i edited post i included how i created thread and from where i found the way to create this... Thank you! –  Dec 04 '18 at 19:35
  • No, it’s not proper. It needs to be a so-called queued connection which comes from managing thread-ownership right. Take a look at my updated answer. – deets Dec 04 '18 at 22:22