从 C++ 插件调用 QML 中的 JS 函数

Posted

技术标签:

【中文标题】从 C++ 插件调用 QML 中的 JS 函数【英文标题】:Calling JS function in QML from c++ plugin 【发布时间】:2014-03-13 11:10:15 【问题描述】:

假设我有一个简单的 QML 插件。我定期检查我的对象的一些状态,在这一步我想从 C++ 查询 QML 对象,以这种方式:

插件代码(c++)

class MyItem : public QQuickItem

public:
    MyItem(QQuickItem *parent = 0) :
        QQuickItem(parent)
    
    void timerFunction(SomeObject * obj)
    
        // here I need to call QML function to validate my object, may be in this way:
        callJSFunction("myFunction",obj); // that's what I need
        if(obj->approved) doSomething();
    

QML 文件:

MyItem 
    id: myItem
    property bool someProperty
    function myFunction(obj)
    
        obj.approved = someProperty;
    

我不能仅仅因为对 JS 的调用必须以同步方式来使用信号。我的意思是我需要的是:

在 C++ 代码中,定时器调用函数 timerFunction() 并带有要验证的对象 在 timerFunction() 内部调用 JS 函数并返回结果 之后我继续执行 timerFunction()

所以我的问题 - 有没有办法从 C++ 插件对象调用 JS 函数?

【问题讨论】:

【参考方案1】:

我不能仅仅因为对 JS 的调用必须以同步方式来使用信号。

Qt 中的信号默认是同步的。当你发出一个信号时,所有连接的槽都会被立即调用,并且发出语句只有在所有槽都执行后才会返回。 因此,在您的情况下,让 MyItem 发出一个信号并在 QML 中连接到该信号。 (唯一的例外是在多线程代码中,但我假设您的 MyItem 实例与 QML 引擎位于同一线程中)

您当然可以反过来,从 C++ 调用 JS 函数。我反对这样做,因为它打破了分层——QML 层应该访问 C++ 层,而不是相反。 无论如何,要从 C++ 调用 JS 函数,请使用 QMetaObject::invokeMethod。有关详细信息,请查看有关 Interacting with QML Objects from C++ 的文档。

【讨论】:

谢谢@tmcguire!我一直认为信号是异步的。如果我错了,那么我的问题就解决了。

以上是关于从 C++ 插件调用 QML 中的 JS 函数的主要内容,如果未能解决你的问题,请参考以下文章

无法调用QML函数

如何在创建对象时从 QML 调用任意 C++ 函数?

如何从 QML 调用 HTML 函数

从 QML 访问 C++ 函数

QT怎样将一个结构体作为函数参数从C++传递到QML

QML 从入门到放弃 第二卷