如何将数据从QML传递到C ++作为可变引用

时间:2016-12-30 05:02:06

标签: c++ qt qml qt5

我在C ++类中有一个Sub WriteLogFile() Dim iFileNumber As Long Dim strData As String Dim strFileName As String iFileNumber = FreeFile() strData = "Test data" 'the text written in the file strFileName = "C:\test.log" ' the text file Open strFileName For Append Shared As #iFileNumber Print #iFileNumber, strData Close #iFileNumber End Sub 方法,我希望这个方法在不使用信号的情况下,在相同的方法中将数据返回到QML。

我的mehtod声明为:

Q_INVOKABLE

定义为:

Q_INVOKABLE void select_company(int index,QString *out);

当我从QML中的JavaScript函数调用它时:

void Companies::select_company(int index,QString *out) {

    out->clear();
    out->append("out string");
}

我在控制台上输出了这个输出:

var out_str;
data_model.select_company(index,out_str);
console.log(out_str);

是否可以将(JavaScript)变量从QML传递给C ++方法,并使用C ++来修改此变量?如果通过传递指针或引用无法做到这一点,那么(最简单的)其他方法是做什么的呢?

到目前为止我找到的唯一方法是传递qrc:/CompaniesList.qml:56: Error: Unknown method parameter type: QString* 并设置属性,如下所示:

声明:

QJSValue

定义:

Q_INVOKABLE void select_company(int index,QJSValue out);

QML:

void Companies::select_company(int index,QJSValue out) {

    out.setProperty("company_name","Acme, Inc.");
    out.setProperty("identity_id",29673);
}

找出调用C ++方法并立即返回一些数据的所有可能方法会很有趣。

2 个答案:

答案 0 :(得分:1)

如果你想“通过引用传递”并在C ++端编辑JavaScript对象,那么QJSValue就是你要走的路。开箱即用的C ++类型没有直接支持,特定类型有一些转换。

作为指针传递仅适用于QObject派生对象。

请注意,QJSValue仅在Object时才有效,也可能是数组。它不适用于其他类型,因为对象将被复制,更改将在副本上完成,不会反映在原始对象上。

答案 1 :(得分:1)

不是我在意,但是什么阻止你宣布像:

Q_INVOKABLE QString getSomeValueFromCPP(int index) {
 ...
 return value; 
}

然后在QML中:

var val = getSomeValueFromCPP(index);

对于更复杂的结构,如果你需要按值返回某些东西,我建议看一下Q_GADGET方法,它真棒。

P.S。由于评论太多,我决定在这里做一个小小的更新,而不是在评论中。

首先,我想对所有ddriver评论给予一个学分,因为它们都是完全正确的。

首先要做的是审查设计,因为任何QML / C ++交互并不真正考虑初始问题中提到的这种方法。其次,区分基于QObject的类和按值传递的实例的所有权非常重要。如果您要使用基于QObject的分类(并不重要QML或C ++所有权),您应该明确决定谁将成为这些对象的创建者。还要注意,在没有显式父代的情况下在C ++代码中创建并传递到QML引擎的任何QObject都将在某些时候被垃圾收集器破坏。这种非常灵活和强大的方法允许创建非常有效的数据结构,如基于QObject的模型,具有完整的属性支持等。

为避免复杂化,Qt提供了另一种处理结构化数据的方法,以防您只需要将值从C ++传递到QML中(因为我理解的是您正在尝试实现的问题)。这就是Q_GADGETS。这类似于将元数据附加到结构的Q_OBJECT方式,允许它们具有Q_PROPERTIES,完整的MetaType信息(因此qobject_cast将起作用,以及任何QVariant转换),但不包括SLOTS / SIGNALS。

主要区别在于,您可以进行按值传递调用,在这种情况下,您应该对所有权以及实时循环感到烦恼(某些方面)。简单来说,在Q_GADGET返回类型的情况下,QML将获得初始对象的COPY并将其销毁,然后不需要它。

正如ddriver所说,它可以模拟参考参数,然后从QML调用C ++方法,但是我怀疑从我的观点来看它是正确的方法吗?缺乏设计。

在你的问题中,你问的是某种技术,但重点是 - 正确的答案是审查一个设计,因为你要做的不是它应该如何工作。再次,正如ddriver所提到的那样,你应该把C ++部分看作" core"以某种方式提供数据 - 它可以是基于QObject的模型/独立对象或基于Q_GADGET的基于值的实例,而QML部分是"表示"逻辑,它不应该被用来创建/保存C ++想要修改的东西,特别是通过引用。

Ragaring Nulik评论 - 典型的用例是将返回基于Q_GADGET的类从C ++返回到QML中。您不应该尝试通过引用传递这些值以进行C ++代码内的修改。