2017-02-07 175 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

相关问题