Qt 槽和传递数据
Qt slots and passing data
我正在尝试制作一个脚本,其中 Qml 代码可以将数据发送到 c++ 脚本,然后相应地执行一个函数。这部分工作正常,但我还想将执行函数的反馈发送回 Qml。
我有以下代码(这是一个精简的示例,用于测试从 Receiver.cpp 向 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(注意:我也在尝试从这段代码发送数据。我想这就是问题所在)
#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);
}
}
}
我正在使用计时器来显示 text1 和全局变量 GlobalForJs 的实际值,我尝试制作但没有这样做'不工作。在 Connections 部分中,它显示文本实际上发生了变化。但在 Connections 之外它不会改变。
我最好的猜测是,这是因为我在 receiver.cpp
中创建了一个 'new' 连接
所以在简短的总结中,我的问题是:如何将数据从 receiver.cpp(以及将来的其他 cpp 文件)发送到 Qml 文件并显示是吗?
这里有很多解决方案:
在 C++
代码中创建一个信号并在 qml
中连接到它,以便能够从 C++ 方法中获得结果。
slots实际上不仅可以void
而且可以return一个值。但在这种情况下,它会阻塞你的线程并导致 "freeze".
导出可以与之充分交互的对象。这是最适合做这种事情的方式。
我正在尝试制作一个脚本,其中 Qml 代码可以将数据发送到 c++ 脚本,然后相应地执行一个函数。这部分工作正常,但我还想将执行函数的反馈发送回 Qml。
我有以下代码(这是一个精简的示例,用于测试从 Receiver.cpp 向 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(注意:我也在尝试从这段代码发送数据。我想这就是问题所在)
#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);
}
}
}
我正在使用计时器来显示 text1 和全局变量 GlobalForJs 的实际值,我尝试制作但没有这样做'不工作。在 Connections 部分中,它显示文本实际上发生了变化。但在 Connections 之外它不会改变。
我最好的猜测是,这是因为我在 receiver.cpp
中创建了一个 'new' 连接所以在简短的总结中,我的问题是:如何将数据从 receiver.cpp(以及将来的其他 cpp 文件)发送到 Qml 文件并显示是吗?
这里有很多解决方案:
在
C++
代码中创建一个信号并在qml
中连接到它,以便能够从 C++ 方法中获得结果。slots实际上不仅可以
void
而且可以return一个值。但在这种情况下,它会阻塞你的线程并导致 "freeze".导出可以与之充分交互的对象。这是最适合做这种事情的方式。