How do I use opencv python shows on pyqt6 qml?
Unsolved
QML and Qt Quick
-
import sys from pathlib import Path import os import cv2 from PyQt6.QtQml import QQmlApplicationEngine from PyQt6.QtGui import QIcon, QImage from PyQt6.QtWidgets import QApplication from PyQt6.QtCore import Qt, QThread, pyqtSignal, pyqtSlot, QObject from PyQt6.QtQuick import QQuickImageProvider class ThreadCamera(QThread): updateFrame = pyqtSignal(QImage) def __init__(self, parent=None): QThread.__init__(self, parent) def run(self): self.cap = cv2.VideoCapture(0) while self.cap.isOpened(): ret, frame = self.cap.read() if not ret: img = QImage("./images/network.png") self.updateFrame.emit(img) color_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) img = QImage(color_frame.data, color_frame.shape[1], color_frame.shape[0], QImage.Format.Format_RGB888) self.updateFrame.emit(img) class ImageProvider(QQuickImageProvider): imageChanged = pyqtSignal(QImage) def __init__(self): super(ImageProvider, self).__init__(QQuickImageProvider.ImageType.Image) self.cam = ThreadCamera() self.cam.updateFrame.connect(self.update_image) self.image = None def requestImage(self, id, size): if self.image: img = self.image else: img = QImage(600, 500, QImage.Format.Format_RGB888) img.fill(Qt.GlobalColor.black) return img @pyqtSlot() def update_image(self, img): self.imageChanged.emit(img) self.image = img @pyqtSlot() def start(self): print("Starting...") self.cam.start() @pyqtSlot() def killThread(self): print("Finishing...") try: self.cam.cap.release() cv2.destroyAllWindows() except: pass class MainWindow(QObject): def __init__(self): QObject.__init__(self) if __name__ == "__main__": app = QApplication(sys.argv) app.setWindowIcon(QIcon("./images/network.png")) engine = QQmlApplicationEngine() #Get Context main = MainWindow() myImageProvider = ImageProvider() engine.rootContext().setContextProperty("backend", main) engine.rootContext().setContextProperty("myImageProvider", myImageProvider) engine.addImageProvider("MyImageProvider", myImageProvider) #Load QML File engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml")) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec())
main.qml
import QtQuick 2.15 import QtQuick.Window import QtMultimedia import QtQuick.Controls 6.3 import QtQuick.Layouts 6.3 import QtQuick.Dialogs Window { visible: true width: 600 height: 500 title: "WebCam" Image { id: feedImage width: parent.width height: parent.height - 50 fillMode: Image.PreserveAspectFit cache: false source: "image://MyImageProvider/img" property bool counter: false function reloadImage() { counter = !counter source = "image://MyImageProvider/img?id=" + counter } } RowLayout { anchors.top: feedImage.bottom anchors.horizontalCenter: feedImage.horizontalCenter Button { id: btnStartCamera text: "Start Camera" onClicked: { myImageProvider.start() } } Button { id: btnStopCamera text: "Stop Camera" onClicked: { myImageProvider.killThread() } } } Connections{ target: myImageProvider function onImageChanged(image) { console.log("emit") feedImage.reloadImage() } } }