2017-08-27 35 views
1

我有C++類用戶我應該使用QVariant還是MyCustomType *將對象從Qml傳遞給C++?

class User : public QObject 
{ 
    Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged) 
    Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) 
    ... 
} 

而且我有按鈕,呼叫點擊時這段代碼設爲Qml簽到形式:

var user = userComponent.createObject() 
user.login = loginTextField.text 
user.password = passwordTextField.text 
signInInteractor.signIn(user) 

SignInInteractor是一個C++類

class SignInInteractor : public QObject 
{ 
    Q_INVOKABLE void signIn(User* user); 
    Q_INVOKABLE void signIn(QVariant user); 
    ... 
} 

和我問題是我應該使用User*還是QVariant作爲參數類型?他們有什麼優點和缺點?

+1

儘可能使用'QObject'派生類型與QML進行交互。不僅更好的類型檢查,它們暴露屬性和可調用方法,而將類型封裝到'QVariant'意味着你的C++函數應該首先識別類型並將變量值賦值給它。如果我需要將不同類型的參數傳遞給該函數,我會使用該變體。 – AlexanderVX

回答

3

您的自定義類型是QObject派生的,所以您可以輕鬆地在QML的QObject *級別上對其進行處理。您將能夠直接訪問屬性,插槽或可調用的功能,而無需額外執行任何操作。

然而,您將不得不添加Q_OBJECT宏,該宏目前在您的代碼中缺失,因此這些類型會獲得MOC處理,從而爲它們生成必要的元數據,這是QtQuick將用於內省的原因。

如果您將它作爲變體傳遞,它將會像一個不透明的指針,您將無法從QML做很多事情,除了傳遞它外。只有當QML不支持類型時纔有意義,QObject更像是一流的公民。

+0

還有'Q_GADGET'類型,當'* Changed'信號的屬性是不需要的。 – Orient

+0

@Orient--不僅僅如此。小工具總是按照價值傳遞,複製,而不是。這意味着你不能通過引用獲取它們,這意味着你不能保留對象標識。爲了使交易更加「甜蜜」,你甚至不能**明確地在指針級別上使用小工具。小工具+指針+ QML是一個不行。這是一個相當嚴格的設計限制。 – dtech

相關問題