簡體   English   中英

如何在C ++中創建對象並在QML中訪問它

[英]How to create object in C++ and access it in QML

我想在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
    }
}

如果要使用重量更輕的QObject版本,可以將Employee設為Q_GADGET。

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

在這種情況下,如果您的員工基於QObject ,那么您根本不需要做任何事情來使用QML中的對象,因為元系統會很小心。 缺點是QObject非常龐大,因此,如果您有數百萬的員工,則絕對不希望這樣做。 但是數以萬計或更少應該沒問題。

而且由於JS不是強類型語言,因此它不是employee e =...而是var e = factory.createEmployee(0)如果要在屬性中鍵入它,則必須將其注冊為QML類型,可以分別使用qmlRegisterType()qmlRegisterUncreatableType()函數作為常規或不可創建函數,后者是可以訪問和使用但不能從QML創建的類型。

我假設您已經將工廠公開為上下文屬性。

如果您不希望您的員工是QObject派生的,那么您將不得不放棄直接使用來自QML的對象 (不,您可以,如vpicaver所述簡單地使用Q_GADGET ),您可以將其注冊到具有Q_DECLARE_METATYPE()的Qt元類型系統,該系統將允許您將它們用作QML的參數, 但要訪問其數據,您將必須使用QObject派生的訪問器/控制器類,該類將從以下位置返回員工數據C ++到QML 或者,您可以使用模型進行管理,並將成員公開為模型角色,在這種情況下,您需要實現QAbstractListModel

另外,從C ++創建基於QObject的對象並在QML中使用它們時,請記住對象的生存期。 您可以明確指定是由QML還是C ++管理所有權和生存期,我在與QML仍在使用中刪除對象有關的問題上有相當一部分,導致崩潰,此時,QML所有權似乎很笨拙,但是行為僅在更復雜,高度動態的情況下才會出現這種情況,對於“典型”的QML使用來說,可能還可以。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM