I have at the moment a simple PySide6 app which uses qml
for image capturing. I want to transport the image to our app but cannot figure out how. I am not sure, if saving QML image is an attempt in the right direction.
import sys
from pathlib import Path
from PySide6.QtCore import QObject, Slot
from PySide6.QtGui import QGuiApplication, QImage
from PySide6.QtQml import QQmlApplicationEngine, QmlElement
QML_IMPORT_NAME = "io.qt.textproperties"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class Bridge(QObject):
@Slot(QImage)
def capture(self, preview):
# Do something with the preview
print(type(preview))
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
# Get the path of the current directory, and then add the name
# of the QML file, to load it.
qml_file = Path(__file__).parent / "simpleCam.qml"
engine.load(qml_file)
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
import QtQuick
import QtQuick.Controls
import QtMultimedia
import io.qt.textproperties
ApplicationWindow {
id: mainFrame
width: 640
height: 480
visible: true
title: qsTr("Cam Test")
Bridge {
id: bridge
}
Rectangle {
width: 640
height: 400
MediaDevices {
id: mediaDevices
}
CaptureSession {
imageCapture: ImageCapture {
id: capture
}
camera: Camera {
id: camera
}
videoOutput: output
}
VideoOutput {
id: output
anchors.fill: parent
}
Button {
id: startCamButton
text: "Start Cam"
anchors.top: output.bottom
anchors.left: output.left
onClicked: {
camera.start()
camImage.opacity = 0
}
}
Button {
id: takePicButton
text: "take pic"
anchors.top: output.bottom
anchors.left: startCamButton.right
onClicked: {
capture.capture()
camImage.opacity = 1
}
}
Image {
id: camImage
anchors.fill: parent
source: capture.preview
}
}
}
In the Button
with id: takePicButton
I want to transport the image to the PySide6 Bridge. If I add to theonClicked
Signal bridge.capture(capture.preview)
I got the Error:
TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.`
How can I solve this problem?
You should use the imageCaptured
signal.
Change:
imageCapture: ImageCapture {
id: capture
}
To:
imageCapture: ImageCapture {
id: capture
onImageCaptured: function(req_id, preview){bridge.capture(req_id, preview)}
}
And change in main.py:
@Slot(QImage)
def capture(self, preview):
# Do something with the preview
print(type(preview))
To:
@Slot(int, QImage)
def capture(self,req_id, preview):
print(req_id)
print(type(preview))
Working example here.
You might want to look at this answer for other use cases.