Sep-03-2025, 04:01 PM
Hi,
The app works, however if I don't stop the camera stream before closing then (sometimes) I get the error:
FATAL: exception not rethrown
Can you spot why, or even tell me how to find out what it is referring to... I've tried to catch the app close and propagate and close things properly (namely the thread handling CV2)
Many thanks
The app works, however if I don't stop the camera stream before closing then (sometimes) I get the error:
FATAL: exception not rethrown
Can you spot why, or even tell me how to find out what it is referring to... I've tried to catch the app close and propagate and close things properly (namely the thread handling CV2)
Many thanks
"""
FATAL: exception not rethrown
Aborted (core dumped)
"""
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QKeyEvent
import PyQt5.QtCore as QtCore
import sys
import signal # for exit
import cv2
class w_cam_view(QWidget):
def __init__(self):
super(w_cam_view, self).__init__()
self.layout = QVBoxLayout()
self.lbl_img = QLabel()
self.lbl_img.setMaximumSize(200, 200)
self.layout.addWidget(self.lbl_img)
# VIEW TOOLBAR
self.layout2 = QHBoxLayout()
self.txt_addr = QLineEdit(self)
self.txt_addr.setText("0")
self.txt_addr.setFixedWidth(120)
self.layout2.addWidget(self.txt_addr)
self.btn_start = QPushButton("Start")
self.btn_start.clicked.connect(self.feed_start)
self.layout2.addWidget(self.btn_start)
self.btn_stop = QPushButton("Stop")
self.btn_stop.clicked.connect(self.feed_stop)
self.layout2.addWidget(self.btn_stop)
# OPENCV THREAD
self.cam_thread = cam_thread()
self.cam_thread.update_img.connect(self.update_img)
self.layout.addLayout(self.layout2)
self.setLayout(self.layout)
def update_img(self, img):
self.lbl_img.setPixmap(QPixmap.fromImage(img).scaled(self.lbl_img.size(), aspectRatioMode=QtCore.Qt.KeepAspectRatio))
def feed_stop(self):
self.cam_thread.on_stop()
def feed_start(self):
self.cam_thread.cam_path = int(self.txt_addr.text())
self.cam_thread.on_start()
def on_exit(self):
print("EXIT widget")
self.cam_thread.on_exit()
class cam_thread(QThread):
update_img = pyqtSignal(QImage)
cam_path = 2 #0
resize_w = 640
resize_h = 480
def run(self):
self.ThreadActive = True
try:
# INIT CV STREAM
cap = cv2.VideoCapture(self.cam_path)
cap.setExceptionMode(True)
while self.ThreadActive:
ret, frame = cap.read() # throws exception if no stream!
if ret:
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img_f = cv2.flip(img, 1)
img_qt = QImage(img_f.data, img_f.shape[1], img_f.shape[0], QImage.Format_RGB888)
img_qt = img_qt.scaled(self.resize_w, self.resize_h, Qt.KeepAspectRatio)
self.update_img.emit(img_qt)
except:
print("Error caught!")
self.on_stop()
def on_stop(self):
self.ThreadActive = False
self.quit()
def on_start(self):
self.start()
def on_exit(self):
print("EXIT worker")
self.on_stop()
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'Cam'
self.left = 10
self.top = 10
self.width = 1000
self.height = 400
self.init_ui()
def init_ui(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# ADD WIDGETS
self.w_cam = w_cam_view()
# LAYOUT
layout = QVBoxLayout()
layout.addWidget(self.w_cam)
# SET CONTENT
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def on_exit(self):
print("EXIT window")
self.w_cam.on_exit()
def closeEvent(self, event):
print('Window closing...')
self.on_exit()
event.accept()
#ex = None
def exit_application(signum, frame):
print("exit_application")
#ex.on_exit()
QApplication.quit()
if __name__ == "__main__":
# START QT AND APP
app = QApplication(sys.argv)
ex = App()
ex.show()
try:
signal.signal(signal.SIGINT, exit_application)
sys.exit(app.exec_())
except KeyboardInterrupt:
signal.signal(signal.SIGINT, exit_application)
sys.exit(app.exec_())
#sys.exit(0)
#signal.signal(signal.SIGINT, exit_application)
#sys.exit(app.exec_())
