【问题标题】:Qt slots and passing dataQt 插槽和传递数据
【发布时间】:2015-06-17 09:42:30
【问题描述】:

我正在尝试制作一个脚本,其中 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 中创建了一个“新”连接

简而言之,我的问题是:如何将数据从 receiver.cpp(以及将来的其他 cpp 文件)发送到 Qml 文件并显示?

【问题讨论】:

    标签: c++ qt qml signals-slots slot


    【解决方案1】:

    这里有很多解决方案:

    1. 在C++ 代码中创建一个信号并在qml 中连接到它,以便能够从C++ 方法中获取结果。

    2. Slots 不仅可以是void,还可以实际返回一个值。但在这种情况下,它会阻塞你的线程并导致“冻结”。

    3. 导出一个可以与之完全交互的对象。这是做这些事情的最合适的方式。

    【讨论】:

    • 非常感谢您的快速回复。您是否对第 3 个解决方案有教程/额外说明?我对 Qt 很陌生,真的找不到任何明确的例子来说明如何做到这一点。
    • @Martijn 阅读:doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.htmldoc.qt.io 上关于C++ 和QML 的所有内容都得到了很好的解释。那里的信息可供新手使用。先在那里寻找更多问题。
    • 非常感谢!我已阅读文档并按照文档中链接的教程进行操作,现在我的代码可以正常工作了。
    • 好消息,@Martijn!接受它作为答案,然后让人们知道您的问题是可以解决的。
    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 2011-05-08
    • 1970-01-01
    • 2013-11-11
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多