从QML动态创建C++对象

Dynamically create C++ object from QML

本文关键字:C++ 对象 创建 动态 QML      更新时间:2023-10-16

我想从QML动态创建一个C++对象。我创建了一个名为CarQObject派生类,并使用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,因为没有定义Car*.qml文件,因为Car是在C++中定义的。

您可以使用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也有。CCD_ 23和其他替代方案只是用于将其引导到qml上。因此,如果你想在C++端传递一个qml对象,那么你唯一需要的就是有一个带有Car*参数的slot/invocable函数。在slot/invocable函数中,必须指定将对象所有权转移到qml引擎。

假设你有一个类似的汽车类,

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;
};

还有一个类似的Store类,

class Store : public QObject {
    Q_OBJECT
public:
    explicit Store(QObject *parent = Q_NULLPTR);
    Q_INVOKABLE void sell(Car *car);
};

如果你在qml上把你的Car对象传递给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
}