我在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 ++方法并立即返回一些数据的所有可能方法会很有趣。
答案 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 ++代码内的修改。