'How to solve QQuickPaintedItem crash and not rendering?
I try to show the stream of preprocessed Images so I create a custom QQuickPaintedItem to paint images
The problem is that when the image change, Nothing happens just the application crashes but the print statement of the paint method still prints, and the mouse cursor looks like + sign.
here is my LiveCamera subclass from QQuickPaintedItem
class LiveCamera(QQuickPaintedItem):
imageChanged=Signal(QImage)
def __init__(self):
super().__init__()
self.setRenderTarget(QQuickPaintedItem.FramebufferObject)
self.m_image = QImage("C://Users//Hassan//Documents//python-gui-projects//PortMafiaSecurity//images//loading.jpg")
def paint(self,painter: QPainter):
print('hey')
if self.m_image.isNull(): return
img = self.m_image.scaled(self.size().toSize(),Qt.KeepAspectRatioByExpanding ,Qt.SmoothTransformation)
painter.drawPixmap(QPoint(),QPixmap.fromImage(img))
@Property(QImage, notify=imageChanged)
def image(self):
return self.m_image
@image.setter
def image(self, image):
if self.m_image == image: return
self.m_image = image
self.imageChanged.emit(self.m_image)
#self.paint(QPainter())
self.update()
Here is main.py
class CamThread(QThread):
def __init__(self,UI):
super().__init__()
self.UI=UI
def run(self):
cap = open_images_capture(args.input, args.loop)
frame_processor = FrameProcessor(args)
frame_num = 0
output_transform = None
while True:
start_time = perf_counter()
frame = cap.read()
if frame_num == 0:
output_transform = OutputTransform(frame.shape[:2], args.output_resolution)
detections = frame_processor.process(frame)
frame = draw_detections(frame, frame_processor, detections, output_transform)
frame_num += 1
h, w, ch = frame.shape
p = QImage(frame.data, h, w,QImage.Format_RGB888)
self.UI.changeImage.emit(p)
class MainThread(QObject):
def __init__(self):
QObject.__init__(self)
self.cam=CamThread(self)
changeImage=Signal(QImage)
@Slot(bool)
def click(self,first):
if first:
self.cam.run()
else:
self.cam.quit()
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
main = MainThread()
engine.rootContext().setContextProperty("cam_recording", main)
qmlRegisterType(LiveCamera, "LiveCameraPlugin", 1, 0, "LiveCamera")
engine.load(os.fspath(Path(__file__).resolve().parent / "qml/main.qml"))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
Here is Qml
Rectangle{
x: 72
y: 84
width: 649
height: 366
LiveCamera{
id:camera
anchors.fill: parent
}
}
LeftMenuBtn {
//some stuff
}
Connections{
target: cam_recording
function onChangeImage(img){
camera.image=img
}
}
Is there a way to solve that problem, I tried a lot to search for a solution but I didn't find it also I tried QtQuickImageProvider same problem so is there a better way?
Solution 1:[1]
According to the screenshot, this isn't a crash. The program seems to be too busy (on the main/gui thread) to respond to user interaction, resulting in Windows saying the application is not responsive.
To debug such a problem, you should use a debugger, pause the program and see what he is doing (on the main thread).
The problem, in this case, is that you are running CamThread::run (which executes an infinite loop) inside the main thread, instead of running it on a separate thread as intended. You shouldn't call QThread::run explicitly, but call QThread::start, which will start a new thread and execute the QThread::run function on that new thread.
Note that QThread::quit does nothing in your case, as by reimplementing QThread::run, the QEventLoop isn't started on that thread. Either you should start the event loop or you should implement your own signal, to interrupt the infinite loop inside CamThread::run to let the thread finish gracefully.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Parisa.H.R |
