从 QML 动态创建 C++ 对象

Dynamically create C++ object from QML

我想从 QML 动态创建一个 C++ 对象。我创建了一个名为 CarQObject 派生 class,并使用 qmlRegisterType<Car>("org.qtproject.models", 1, 0, "Car"); 将其暴露给 QML。在 QML 中,我可以像这样实例化一个 Car 对象:

Car {
    id : car_1
    carName : "H1"
    carBrand : "Hummer"
    carPrice : 125000
} 

然后使用 car_1 对象并在需要时轻松将其传回 C++。但我想要的是在 QML 中动态创建一个 Car 对象,这样我就可以将它传递回 C++

我试过了:

MouseArea
{
    anchors.fill: parent
    onClicked: {
        component = Qt.createQmlObject("Car { id: car_1; carName : \"H1\"; carBrand : \"Hummer\"; carPrice : 125000; }",
                                       parent, "dynamicSnippet1");

        myCarModel.appendRowFromQml(component);
    }
}

但运气不好。使用静态方法,效果很好:

MouseArea
{
    anchors.fill: parent
    onClicked: {
        myCarModel.appendRowFromQml(car_1);
    }
}

有没有办法从 QML 端动态创建 C++ 对象?我也不能使用 Qt.createComponent 因为没有 *.qml 文件其中定义了 Car,因为 Car 是在 C++.[=33= 中定义的]

您可以使用 Loader

像这样:

Loader {
   id: carLoader
   active: false
   sourceComponent:
   Car {
       id : car_1
       carName : "H1"
       carBrand : "Hummer"
       carPrice : 125000
   } 

MouseArea
{
    anchors.fill: parent
    onClicked: carLoader.active:true
}

正如我在评论中所说,问题是变量component,当时不存在。

因此,要解决此问题,只需替换以下代码:

onClicked: {
    component = Qt.createQmlObject(...);

作者:

onClicked: {
    var component = Qt.createQmlObject(...);

其实所有的qml对象都是动态分配的。在你的情况下 Car 也有。 Loader 和其他替代方案只是为了通过 qml 引导它。所以如果你想在 C++ 端传递一个 qml 对象,你唯一需要的是一个带有 Car * 参数的 slot/invokable 函数。在您的 slot/invokable 函数中,您必须指定您正在将对象所有权交给 qml 引擎。

假设你有一辆汽车 class 类似这样的东西,

class Car : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)

public:
    explicit Car(QObject *parent = Q_NULLPTR);
    ~Car();

    QString name();
    void setName(const QString &name);

signals:
    void nameChanged();

private:
    QString m_name;
};

还有一家商店class与此类似,

class Store : public QObject {
    Q_OBJECT
public:
    explicit Store(QObject *parent = Q_NULLPTR);

    Q_INVOKABLE void sell(Car *car);
};

如果您将 Car 对象传递给 qml 上的 Store 对象,

Car {
    id: car1
    name: "H1"
}

MouseArea {
    anchors.fill: parent
    onClicked: Store.sell(car1);
}

那么你必须在你的销售函数中指定对象所有权,

void Store::sell(Car *car)
{
    qDebug() << car->name() << "just sold!!";
    QQmlEngine::setObjectOwnership(car, QQmlEngine::CppOwnership);
    delete car; // proof of the car is dynamically allocated
}