我想在C ++中使用工厂类来创建我可以在QML中使用/访问的对象。但是如何在QML中访问这样新创建的对象?这可以用javascript吗?
我在C ++中的工厂类创建了一个employee
对象,可以是Manager
,SalesPerson
或Engineer
类型,所有这些都来自Employee
。这是代码:
class EmployeeFactory : public QObject
{
Q_OBJECT
public:
enum
{
MANAGER,
SALES_PERSON,
ENGINEER
};
explicit EmployeeFactory(QObject *parent = 0);
Q_INVOKABLE Employee *createEmployee(int type)
{
if (type == MANAGER )
{
qDebug() << "createEmployee(): Manager created";
return new Manager;
}
else if(type == SALES_PERSON)
{
qDebug() << "createEmployee(): SalesPerson created";
return new SalesPerson;
}
else if(type == ENGINEER)
{
qDebug() << "createEmployee(): Engineer created";
return new Engineer;
}
qDebug() << "createEmployee(): Nothing created";
return 0;
}
signals:
public slots:
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
EmployeeFactory * factory = new EmployeeFactory;
qmlRegisterType<Employee>("MyModel", 1, 0, "employee");
engine.rootContext()->setContextProperty("factory", factory);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
现在,在我的QML代码中,我想创建员工并访问它。
Window {
visible: true
MouseArea {
anchors.fill: parent
onClicked: {
// how do I access the return value `employee` here or how
// do I return/access employee here
employee e = factory.createEmployee(0) // This doesn't work, result in Expected token ';' error
// once I have the employee, I would like to set its attributes like
// e.name: "David"
}
}
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
}
答案 0 :(得分:1)
如果您的员工基于QObject
,那么在这种情况下,您根本不需要做任何事情来使用QML中的对象,因为元系统会照顾。缺点是QObject
非常庞大,所以如果你有数百万的员工,你肯定不希望这样。但是数万或更少应该没问题。
由于JS不是强类型语言,因此它不是employee e =...
而是var e = factory.createEmployee(0)
如果要在属性中键入它,则必须将其注册为QML类型,它可以分别使用qmlRegisterType()
和qmlRegisterUncreatableType()
函数作为常规函数或非可创函数,后者是您可以访问和使用但不能从QML创建的类型。
我假设您已将工厂暴露为上下文属性。
如果你不希望你的员工被QObject
派生,那么你将不得不放弃直接使用来自QML的对象(不,你没有,你可以简单地使用Q_GADGET
作为vpicaver注明),您可以使用Q_DECLARE_METATYPE()
将它们注册到Qt元类型系统,这将允许您将它们用作QML的参数,但是为了访问他们的数据,您将不得不使用。或者您可以使用模型来管理,并将成员公开为模型角色,在这种情况下,您需要实现例如QObject
派生的访问者/控制器类,它将员工数据从C ++返回到QML QAbstractListModel
。
此外,在从C ++创建基于QObject
的对象并在QML中使用它们时,请记住对象的生命周期。您可以明确指定QML或C ++是否管理所有权和生命周期,并且我已经公平地分享了与QML删除对象相关的问题,同时仍然在使用,导致崩溃,此时QML所有权似乎相当笨重,但行为仅在更复杂,高度动态的场景中展示,对于“典型”QML使用,它可能是好的。
答案 1 :(得分:1)
如果你想要一个较轻的QObject版本,你可以让Employee成为Q_GADGET。