2017-02-07 129 views
1

我試圖創建自定義類實例並將其傳遞給具有相應參數的Q_INVOKABLE函數。 我試圖做一個例子來指出我試圖做什麼。所以基本上我有一個Foo類和另一個帶有Foo作爲參數的函數的Bar類。我想在QML中調用這個函數,但我不知道如何實例化Foo來將它作爲該函數的參數傳遞。將自定義C++類型傳遞爲QML函數參數

編輯 - 關於主要目標的更多信息:

真正的目標是擁有具有自定義類對象列表的子類化QAbstractItemModel。該列表將使用模型data()函數表示。該模型應該用QML中的一些視圖來表示。我也想在運行時填充模型。所以模型類應該有一個函數,它接受一個自定義類實例並將其附加到內部列表中。所以我的方法是在qml中創建並傳遞自定義類實例。我還沒有找到任何可以做這種類型的例子。 這裏是我已經有了:

foo.h中

class Foo : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QString name READ getName WRITE setName) 
public: 
    Foo(QString fooName, QObject *parent = 0) : QObject(parent){ 
     name = fooName; 
    }   
    QString getName() const { 
     return name; 
    } 
    void setName(const QString &value){ 
     name = value; 
    }  
private: 
    QString name; 
}; 

Bar.h

class Bar : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit Bar(QObject *parent = 0) : QObject(parent){} 

    Q_INVOKABLE void addFoo(const Foo &foo){ 
     fooList.append(foo); 
    } 
private: 
    QList<Foo> fooList; 
}; 

的main.cpp

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 

    QQmlApplicationEngine engine; 
    qmlRegisterType<Foo>("Test", 1, 0, "Foo"); 
    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 
    engine.rootContext()->setContextProperty("bar", new Bar());  
    return app.exec(); 
} 

main.qml

import Test 1.0 

Window {  
    Button { 
     id: addFoo 
     text: "Add new Foo to Bar" 
     onClicked: { 
      bar.addFoo(????) 
     } 
    } 
} 
+0

作爲一般規則,設置背景屬性之前加載QML。在加載引用上下文屬性的QML之前,上下文屬性*必須設置*。它仍然可以工作,但你可以因此而招致奇怪的錯誤。 – BaCaRoZzo

回答

1

你要麼做Foo實例化,通過給它一個構造函數,可以不帶參數調用,然後使用由CMLDMR建議的辦法,或者你加一個「工廠」功能可以創建實例。

在您可能需要與Foo*工作的工廠函數的返回值和addFoo()或更改Foo的參數是一個值類與Q_GADGET宏屬性,而不是從QObject

獲得後者的情況下

鑑於您在Foo中沒有信號,我會推薦後者。

大致是這樣的:

class Foo 
{ 
    Q_GADGET 
    Q_PROPERTY(...) 

// .... 
}; 


class Bar : public QObject 
{ 
// ... 

    Q_INVOKABLE Foo createFoo(const QString &name); 
    Q_INVOKABLE void addFoo(const Foo &foo); 
}; 

編輯:這還需要

qRegisterMetaType<Foo>(); 
+0

感謝您的回答。我收到以下錯誤,因爲我更改了代碼,如上所述:「錯誤:未知方法返回類型:Foo」。我錯過了什麼? – Matthias

+0

這是編譯器錯誤還是來自QML環境? –

+0

它來自qml環境,因爲我稱之爲createFoo函數。 – Matthias

1

你應該傳遞對象在QML之前創建一個對象。 來源:Qt5 C++ GUI Programming Cookbook. Lee Zhi Eng,頁:37

import Test 1.0 

Window { 
    Foo { 
    id: Foo_object 
    }  
    Button { 
     id: addFoo 
     text: "Add new Foo to Bar" 
     onClicked: { 
      bar.addFoo(Foo_object) 
     } 
    } 
} 
+0

但我想動態創建Foo對象不只是預定義的數量。還是我可以總是使用相同的?如果我喜歡你說我得到以下錯誤:「錯誤:未知的方法參數類型:Foo」 – Matthias

+0

@Matthias這真的很難幫助,因爲它不清楚你想給這些對象的一生。 「我可以一直使用相同的」只有一個答案:「這實際上取決於你想達到的目標」。但這是我們在這裏無法輕易推斷出來的。一般來說,您可以通過遵循文檔[此處](http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html)或者使用['Instantiator'](http ://doc.qt.io/qt-5/qml-qtqml-instantiator.html)。 – BaCaRoZzo

相關問題