Unsolved Invoke from C++ a QML function
-
Hi I am new with Qt. I am using Qt on my RPI3.
I found a QML example which is Tesla Car instrument cluster. You can access full code from here or here.I successfully created project and debug it. Now I am trying to change a value in the QML code from C++ side. There is a timer in my C++ code every 30 seconds I am trying to change speed value in the QML code with using
QMetaObject::inokeMethod():
function. I read all examples in here.Here is C ++ code
#ifndef MYTIMER_H #define MYTIMER_H #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlComponent> #include <QTimer> #include <QtDebug> class MyTimer : public QObject { Q_OBJECT public: MyTimer(); QTimer *timer; int i=0; public slots: void MySlot(); }; #endif // MYTIMER_H #include "mytimer.h" MyTimer::MyTimer() { timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(MySlot())); timer->start(10000); } void MyTimer::MySlot() { i++; if(i==3) { i=0; QQmlEngine engine; QQmlComponent component(&engine,QUrl(QStringLiteral("qrc:/Speedometer.qml"))); QObject *object = component.create(); QVariant speeds=100; QVariant returnedValue; QMetaObject::invokeMethod(object,"speedNeedleValue", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, speeds)); qDebug() << "From QML"<< returnedValue.toString(); delete object; } }
Here is QML
import QtQuick 2.4 import QtGraphicalEffects 1.0 Rectangle { color: "transparent" SpeedNeedle { id: speedoNeedle anchors.verticalCenterOffset: 0 anchors.centerIn: parent focus: true Keys.onPressed: { if (event.key == Qt.Key_A) { speedNeedleValue(100) } } function speedNeedleValue(speeds) { speedoNeedle.value = speeds return ": I am here" } }
If I press the "A" button my
speedNeedleValue();
function is working. And in debug page I can get the return datareturn ": I am here"
.
Problem is I can't set thespeeds
argument with invoke function.
Here is the debug page :
Every time interrupt I can get "I am here". but I also get " JIT is disabled.... " warning too.
Thank you for your answers. -
@Sek0 said in Invoke from C++ a QML function:
QQmlEngine engine;
You are creating a new (and completely separate!) QML engine every time your timer fires. So your main QML scene never gets the signal.
Get your main QML engine in MyTimer class, look for your rectangle (you need to give it an
objectName
and then search for it in QML eingine's children), then invoke thespeedNeedleValue
function.However, this approach is highly unusual. A better way is to expose your MyTimer class to QML, like this:
engine.rootContext()->setContextProperty("myTimer", &mytimer);
And then in your QML code you can connect to the signal directly:
Connections { target: myTimer onTimeout: { console.log("I'm here!") } }
You need to add the
timeout()
signal to your MyTimer class of course. -
@sierdzio thank you very much for reply. I will test your comments. I will write after that.