如何将数据从QML传递到C++;作为可变引用 我在C++类中有一个 qy可调用的< /C> >方法,我希望这个方法在相同的方法中,不使用信号,将数据返回到QML。p>

如何将数据从QML传递到C++;作为可变引用 我在C++类中有一个 qy可调用的< /C> >方法,我希望这个方法在相同的方法中,不使用信号,将数据返回到QML。p>,c++,qt,qml,qt5,C++,Qt,Qml,Qt5,我的方法声明为: Q_INVOKABLE void select_company(int index,QString *out); 定义为: void Companies::select_company(int index,QString *out) { out->clear(); out->append("out string"); } 当我从QML中的JavaScript函数调用它时: var out_str; data_model.select_compa

我的方法声明为:

Q_INVOKABLE void select_company(int index,QString *out);
定义为:

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

    out->clear();
    out->append("out string");
}
当我从QML中的JavaScript函数调用它时:

var out_str;
data_model.select_company(index,out_str);
console.log(out_str);
我在控制台上获得以下输出:

qrc:/CompaniesList.qml:56: Error: Unknown method parameter type: QString*

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

到目前为止,我找到的唯一方法是通过传递一个
QJSValue
并为其设置属性,如下所示:

声明:

Q_INVOKABLE void select_company(int index,QJSValue out);
定义:

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

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

查找所有调用C++方法并立即返回一些数据的方法将是有趣的。

< P>如果你想“通过引用”并在C++侧编辑JavaScript对象,那么<代码> QJSValue >是方法。没有直接支持C++类型的框,对于特定类型有一些转换。

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


请记住,
QJSValue
仅当它是一个
对象,也可能是一个数组时才起作用。它不适用于其他类型,因为对象将被复制,更改将在副本上完成,并且不会反映在原始对象上。

我不介意,但是什么阻止了您声明以下内容:

Q_INVOKABLE QString getSomeValueFromCPP(int index) {
 ...
 return value; 
}
然后在QML中:

var val = getSomeValueFromCPP(index);
对于更复杂的结构,如果您需要按值返回某些内容,我建议您看看Q_GADGET方法,这非常棒

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

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

首先,要做的是回顾一个设计,因为任何QML/C++交互都没有真正考虑到在初始问题中提到的方法。其次,区分基于QObject的类和按值传递的实例的所有权非常重要。如果您要使用基于QObjt的类(不考虑QML或C++所有权),您应该清楚地决定谁将成为这些对象的创建者。还要注意,在没有显式父代并传递到QML引擎的C++代码中创建的任何QObjts都会被垃圾收集器在某个时间点销毁。这是一种非常灵活且功能强大的方法,允许创建非常高效的数据结构,如基于QoObject的模型以及完整的属性支持等

为了避免并发症,QT提供了另一种处理结构化数据的方法,以防您只需要将值从C++传递到QML(因为我理解了一个问题,那就是您正在努力实现的问题)。这就是Q_小玩意。这是一种类似于Q_对象的方式,将元数据附加到结构上,允许它们具有Q_属性和完整的元类型信息(因此,qobject_转换将与任何QVariant转换一起工作),但不包括插槽/信号

主要的区别在于,您可以进行传递值调用,在这里您不应该(在某种程度上)为所有权和生命周期操心。简单地说,在Q_GADGET的情况下,返回类型QML将获得初始对象的一个副本,并将其销毁,然后不再需要它

如ddRever中提到的,可以模拟引用参数,然后从QML调用C++方法,但是我怀疑,从我的观点来看,这是正确的方式,它缺乏设计。 在你们的问题中,你们问的是某些技术,但重点是——正确的答案是审查一个设计,因为你们试图做的并不是它应该如何工作。同样,DJEAR提到,你应该把C++部分看作是“核心”,以某种方式提供数据——它可以是基于QOGADGET的QObjas-基于模型/独立对象或基于值的实例,而QML部分是“表示”逻辑,它不应该用来创建/保存C++所假设修改的东西,尤其是通过引用。p>

Ragaring Nulik评论-典型的用例是将QQoGoGET类从C++返回到QML。你不应该通过引用这些值来修改C++代码中的修改。

@ AlexanderVX,在该代码中缺少验证,必须检查jsCalBay.ISCabable(),然后才可以调用它。但是,我不想声明函数,我希望Qt让我修改C++端的JavaScript值。这里的想法是从C++修改原来的参数对象,它不是属性Word.qyInvcQueQStGETNEVALL(index,OLDVAL);它要么是通过值(我认为这是最干净的方式),要么是QObject和属性的变化。。您覆盖了旧的值,所以我认为没有必要不使用返回类型..您可以返回类似typedef struct{Q_GADGET int v1;QString v2;..};这是一个非常轻量级的实现,代码看起来非常干净;当然,您可以从Q_INVOKABLES返回它们..我想我理解您的意思=)对不起,今天早点开始,当然您需要在Q_GADGET实现中定义Q_属性,但我相信这是显而易见的..这种方法会奏效,我个人不喜欢的是,C++中的所有方法都是非常抽象的,所有的参数都是相同的,所以很难读懂,容易出错。但它肯定会起作用,有时会有所帮助=)
var val = getSomeValueFromCPP(index);