I am trying to make a script in which the Qml code can send data to the c++ script and then executes a function accordingly. This part is working fine, but i also want to send feedback from the executed function back to the Qml.
I have the following code (It is a stripped down example to test the sending of data from Receiver.cpp to the Qml)
Main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "receiver.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Receiver receiver;
QQmlContext* ctx = engine.rootContext();
ctx->setContextProperty("receiver", &receiver);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
Reciever.cpp(Note: I am trying to send the data from this code too. I guess this is where it goes wrong)
#include "receiver.h"
#include <QDebug>
#include <QQmlApplicationEngine> //For sending to QML
#include <QQmlContext> //For sending to QML
Receiver::Receiver(QObject *parent) :
QObject(parent)
{
}
int counter = 0;
void Receiver::receiveFromQml(int count) {
qDebug() << "Received in C++ from QML:" << count;
//For sending to QML start
QQmlApplicationEngine engine;
Receiver receiver;
QQmlContext* ctx = engine.rootContext();
ctx->setContextProperty("receiver", &receiver);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
//For sending to QML end
receiver.sendToQml(counter); //Send to the QML
counter++;
}
Reciever.h
#ifndef RECEIVER_H
#define RECEIVER_H
#include <QObject>
class Receiver : public QObject
{
Q_OBJECT
public:
explicit Receiver(QObject *parent = 0);
signals:
void sendToQml(int count);
public slots:
void receiveFromQml(int count);
};
#endif // RECEIVER_H
Main.qml
import QtQuick 2.2
import QtQuick.Window 2.1
Window {
id: test
visible: true
width: 500
height: 500
property variant globalForJs: 10;
Item {
Timer {
interval: 1000; running: true; repeat: true
onTriggered: console.log("Real text value:", text1.text, " Global for JS:", globalForJs);
}
}
MouseArea {
anchors.fill: parent
onClicked: {
receiver.receiveFromQml(42);
}
Text {
id: text1
x: 193
y: 329
text: globalForJs
font.pixelSize: 12
}
}
Text {
text: qsTr("Press me to send a signal to C++")
anchors.centerIn: parent
}
Connections {
target: receiver
onSendToQml: {
console.log("Received in QML from C++: " + count);
globalForJs = count;
console.log(text1.text);
console.log("Real text value:2", text1.text, " Global for JS:", globalForJs);
}
}
}
I am using the timer to show the real values of text1 and the global variable GlobalForJs I tried to make but which didn't work. Inside the Connections part it displays that the text in fact changes. But outside of the Connections it does not change.
My best guess is that it is due to the fact that I create a 'new' connection in the receiver.cpp
So in a short summary my question is: How can I send data from receiver.cpp(and in the future other cpp files) to the Qml file and display it?
Here are a lot of solutions:
Create a signal in
C++
code and connect to it inqml
to be able to get results from C++ method.Slots can be not only
void
but also return a value actually. But in this case it will block your thread and cause a "freeze".Export an object with which you can interact fully. This is the most suitable way to do such things.