can't find my qmlRegisteredType on rootObject() children
-
Hi
I am trying to cast qml Camera to QCamera for reading frames via QVideoProbe, for this, I registered the class and call the camera initialization method, which needs a QQmlApplicationEngine, to do this, I need to take Engine from the instance of the registered class, but I cannot find it among rootObjects, there is some snippets:QCamera initialisation:
void ImageProvider::initCamera() { QObject *qmlCamera = engine->rootObjects().at(0)->findChild<QObject*>("qmlCam"); camera = qvariant_cast<QCamera*>(qmlCamera->property("mediaObject")); connect(&probe,&QVideoProbe::videoFrameProbed,this,&ImageProvider::handleFrame); probe.setSource(camera); }
main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "QtAndroidTools.h" #include "imageprovider.h" Q_DECL_EXPORT int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif QGuiApplication app(argc, argv); qmlRegisterType<ImageProvider>("com.myself", 1, 0, "Provider"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url, &engine](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); ImageProvider *imageProvider = engine.rootContext()->findChild<ImageProvider *>("obj"); qDebug()<<engine.rootObjects().at(0)->children(); imageProvider->Init(&engine); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
main.qml
import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Window 2.12 import QtQuick.Dialogs 1.3 import com.myself 1.0 ApplicationWindow { id: page visible: true width: 360 height: 520 Provider { id:obj } Component { id: mainPg BannerTest {} } StackView { id: stackView anchors.fill: parent initialItem: mainPg } }
in general, I need my provider to be in BannerTest, since the camera is launched from there, but for now I need to at least understand how to find it in main
qDebug()<<engine.rootObjects().at(0)->children(); output is (QQuickRootItem(0xdaa7e520), StackView_QMLTYPE_3(0xdf3a39a0))
As you can see, there is no probider instance, can you tell me what i'm doing wrong?
-
@kshegunov
Indeed, the further I dug into this problem, the more difficult it was to see the solution that lay on the surface, thank you all very much for your advice, it really helped to solve my problem.So, perhaps someone will be useful, the solution:
in main.cpp:qmlRegisterType<ImageProvider>("com.myself", 1, 0, "Provider");
in ImageProvider:
void ImageProvider::initCamera() { QQmlEngine * contextEngine = QQmlEngine::contextForObject(this)->engine(); QQmlApplicationEngine *engine = qobject_cast<QQmlApplicationEngine*>(contextEngine); QObject *qmlCamera = engine->rootObjects().at(0)->findChild<QObject*>("qmlCam"); camera = qvariant_cast<QCamera*>(qmlCamera->property("mediaObject")); connect(&probe,&QVideoProbe::videoFrameProbed,this,&ImageProvider::handleFrame); probe.setSource(camera); }
in qml:
Provider { id: obj objectName: "object" } onClicked:{ stackView.push("qrc:/PreviewScreen.qml") obj.initCamera() }
-
I really don't understand what you're attempting, to be honest. What is
BannerTest
and why should be there anything within it, as it appears empty?@Deymos said in can't find my qmlRegisteredType on rootObject() children:
I need to take Engine from the instance of the registered class
https://doc.qt.io/qt-5/qqmlengine.html#qmlEngine
At any time for an object that's part of the QML/Quick tree.
-
@kshegunov
I apologize, maybe I incorrectly expressed my question, in general I have an application essence of which to work with the camera and analyze a person in real time, for this in transition to the analysis page I need to enable the camera. if I initialize and run the camera in Main.qml when app is started, everything works fine, but if I need to initialize the camera later, when switching to the page, difficulties appear, since I need to read frames from the camera via QVideoProbe and transmit to OpenCV, it seems to me this option more efficient than capture 30 times per second, and for this I need to initialize and transfer the camera to the C ++ class when switching to a page with a camera, and here is the essence of my problem, I register the class in which the camera is transmitted, since QmlregisterType support only the standard constructor, I am looking for QML my registered class and trying to convey to him the correct Engine, but the problem is that through Findchild I can't find my registered class, and because of this, I can not call the transmission function of the Engine and therefore convey the camera in C ++ class, I hope this time it matched)I tried to create a camera in main.Qml and create VideoOutput already on the page where the camera should be, and i tried to specify the camera through the
source: camera
but it didn't work out, videoouutput is empty, but still it is not the best way, so the camera will be launched throughout the application and it will cause resource loss, it would be nice if you suggest ways to solve the first problem)
-
@fcarney
As I understand you advise with qmlEngine(this) take Engine from qml instance of ImageProvider, butImageProvider *imageProvider = engine.rootContext()->findChild<ImageProvider *>("obj");
returns null, and I don't understand why, maybe I Incorrectly registering Provider, but it's
qmlRegisterType<ImageProvider>("com.myself", 1, 0, "Provider");
probably the right way to register components in qml.
All I need to pass engine to Image provider for cast Camera to QCamera when page with camera is opened and instance of Camera was created
-
@Deymos said in can't find my qmlRegisteredType on rootObject() children:
ImageProvider *imageProvider = engine.rootContext()->findChild<ImageProvider *>("obj");
"obj" is the id, not the objectName.
For your problem it would be better if the object used qmlEngine in an init routine called from qml.
-
@Deymos said in can't find my qmlRegisteredType on rootObject() children:
As I understand you advise with qmlEngine(this) take Engine from qml instance of ImageProvider, but
ImageProvider *imageProvider = engine.rootContext()->findChild<ImageProvider *>("obj");Yes, but I don't understand why the whole of shenanigans with
findChild
? Since this is your class define a couple of properties and methods and call them as appropriate from QML.returns null, and I don't understand why, maybe I Incorrectly registering Provider, but it's [...]
For Qt5, this is the correct way.
-
@kshegunov
Indeed, the further I dug into this problem, the more difficult it was to see the solution that lay on the surface, thank you all very much for your advice, it really helped to solve my problem.So, perhaps someone will be useful, the solution:
in main.cpp:qmlRegisterType<ImageProvider>("com.myself", 1, 0, "Provider");
in ImageProvider:
void ImageProvider::initCamera() { QQmlEngine * contextEngine = QQmlEngine::contextForObject(this)->engine(); QQmlApplicationEngine *engine = qobject_cast<QQmlApplicationEngine*>(contextEngine); QObject *qmlCamera = engine->rootObjects().at(0)->findChild<QObject*>("qmlCam"); camera = qvariant_cast<QCamera*>(qmlCamera->property("mediaObject")); connect(&probe,&QVideoProbe::videoFrameProbed,this,&ImageProvider::handleFrame); probe.setSource(camera); }
in qml:
Provider { id: obj objectName: "object" } onClicked:{ stackView.push("qrc:/PreviewScreen.qml") obj.initCamera() }
-
Why not have a
camera
property that you bind to? That's what I'd've done. In thesetCamera
method in C++ you can catch the pointer and connect your stuff. I continue to think that all thisfindChild
is unnecessary, not to mention slow.