QQuickPaintedItem崩溃不渲染怎么解决?

How to solve QQuickPaintedItem crash and not rendering?

我尝试显示预处理图像流,所以我创建了一个自定义 QQuickPaintedItem 来绘制图像 问题是,当图像发生变化时,什么也没有发生,只是应用程序崩溃了,但 paint 方法的打印语句仍在打印,鼠标光标看起来像 + 符号。

这是我的 LiveCamera 来自 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()

这里是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_())

这是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
    }
}

有没有解决这个问题的方法,我尝试了很多方法来寻找解决方案,但我也没有找到我也试过 QtQuickImageProvider 同样的问题,请问有更好的方法吗?

这里是Application Crash Moment: Python is not responding

根据屏幕截图,这不是崩溃。该程序似乎太忙(在 main/gui 线程上)无法响应用户交互,导致 Windows 表示应用程序没有响应。

要调试这样的问题,你应该使用调试器,暂停程序,看看他在做什么(在主线程上)。

在这种情况下,问题是您在主线程中 运行 CamThread::run(执行无限循环),而不是在单独的线程中 运行如预期。您不应显式调用 QThread::run,而应调用 QThread::start,这将启动一个新线程并在该新线程上执行 QThread::run 函数。

请注意 QThread::quit does nothing in your case, as by reimplementing QThread::runQEventLoop 并未在该线程上启动。您应该启动事件循环,或者您应该实现自己的信号,以中断 CamThread::run 内的无限循环,让线程优雅地完成。