如何在qml中创建全局函数

6

我想创建一个全局函数,可以在其他qml文件中的任何地方调用。尝试将一个函数放在矩形内部,但在下一个对象中给我语法错误。我不想使用单例,因为语法会像Singleton.foobar。我只想在其他qml中的任何地方使用foobar。

Rectangle {
    function foobar(v) {
        return v * 2;
    }
}

ApplicationWindow { // syntax error here
}
2个回答

5
在根节点(ApplicationWindow)中定义函数。这将是QML在寻找名称之前的最后一个位置,如果没有找到,则会使用C++上下文属性。
请参见此处以了解在QML中解析变量和函数名称的方法。
但是,不可能修改全局对象,因此无法使用真正的全局JS函数。
然而,更有效的方法是始终将其保留在最具体的范围之一,因此使用Identifyer.function()进行引用查找速度更快。库的单例模式不是正确的方法。请参见此处以了解JS库的用法。

点赞了,但是“库的单例模式并不是正确的方法”。难道不应该是相反的吗? - BaCaRoZzo
1
@BaCaRoZzo:你在谈论“使用单例类型代替编译指示库脚本: 如果您正在使用编译指示库脚本来存储应用程序范围的实例数据,请考虑改用QObject单例类型。这应该会导致更好的性能,并且将减少使用JavaScript堆内存。”我认为这是关于全局数据的问题,应该使用适当的类型在Singleton中进行存储。但如果是关于库的话,我认为库是正确的方式。为什么不呢? - derM
1
好的,我完全同意你的观点。只有我需要坚持正确的术语 :) 干得好! - BaCaRoZzo

4
  1. 创建一个具有可调用函数的C++类:
...
class MyCPPObject : public QObject
{
    Q_OBJECT
public:
...
Q_INVOKABLE bool funToCallFromJS(int any, QString args);
...
  1. 在全局空间中创建MyCPPObject对象(规则如下:它必须存在直到引擎存在(这是一些简化,但已足够))
...
MyCPPObject cppobj;
...

使用以下代码将其导出为 QML 和 JS:
...
QJSValue wrapobj = engine.newQObject(&cppobj);
engine.globalObject().setProperty("cppFun", wrapobj.property("funToCallFromJS"));
...

在引擎存在的同时,wrapobj也必须存在(再次简化) 4. 在QML和JS中:

...
if(cppFun(127, "abc"))
    console.log("It works!");
...

注意:我在QML空间和CPP空间中使用了不同的名称,只是为了展示当从JS中使用时可以重命名CPP函数,但当然您也可以使用相同的名称。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接