如何在C ++中创建对象并在QML中访问它

时间:2016-03-15 05:20:36

标签: javascript c++ qt qml factory

我想在C ++中使用工厂类来创建我可以在QML中使用/访问的对象。但是如何在QML中访问这样新创建的对象?这可以用javascript吗?

我在C ++中的工厂类创建了一个employee对象,可以是ManagerSalesPersonEngineer类型,所有这些都来自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
    }
}

2 个答案:

答案 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。

https://doc.qt.io/qt-5/qobject.html#Q_GADGET