簡體   English   中英

如何將數據從QML傳遞到C ++作為可變引用

[英]How to pass data from QML to C++ as a mutable reference

我在C ++類中有一個Q_INVOKABLE方法,我希望這個方法在相同的方法中將數據返回到QML,而不使用信號。

我的mehtod被宣布為:

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:

var retval={};
data_model.select_company(index,retval);
console.log(retval.company_name);
console.log(retval.identity_id);

有趣的是找出所有可能的方法來調用C ++方法並立即返回一些數據。

如果你想“通過引用傳遞”並在C ++端編輯JavaScript對象,那么QJSValue就是你要走的路。 開箱即用的C ++類型沒有直接支持,特定類型有一些轉換。

作為指針傳遞僅適用於QObject派生對象。

請記住, QJSValue只有在它是一個Object時才有效,也可能是一個數組。 它不適用於其他類型,因為將復制對象,並且將在副本上進行更改,並且不會在原始對象上反映。

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

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

然后在QML中:

var val = getSomeValueFromCPP(index);

對於更復雜的結構,如果你需要按值返回一些東西,我建議看一下Q_GADGET方法,它真棒。

PS因為有很多評論我決定在這里做一個小的更新,而不是在評論中。

首先,我想給所有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 ++部分看作是以某種方式提供數據的“核心” - 它可以是基於QObject的模型/獨立對象或基於Q_GADGET的基於值的實例,而QML部分是一個“表示”邏輯,它不應該用來創建/保存C ++想要修改的東西,特別是通過引用。

Ragaring Nulik評論 - 典型的用例是將基於Q_GADGET的類從C ++ 返回到QML。 您不應該嘗試通過引用傳遞這些值以進行C ++代碼中的修改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM