Reputation: 3184
I want to dynamically create a C++
object from QML
. I created a QObject
derived class named Car
and exposed it to QML
using qmlRegisterType<Car>("org.qtproject.models", 1, 0, "Car");
. Inside QML
I am able to instantiate a Car
object like this:
Car {
id : car_1
carName : "H1"
carBrand : "Hummer"
carPrice : 125000
}
and then use the car_1
object and pass it back to C++
with ease if I need to. But what I would like is to create a Car
object dynamically in QML
, so I can pass it back to C++
.
I tried:
MouseArea
{
anchors.fill: parent
onClicked: {
component = Qt.createQmlObject("Car { id: car_1; carName : \"H1\"; carBrand : \"Hummer\"; carPrice : 125000; }",
parent, "dynamicSnippet1");
myCarModel.appendRowFromQml(component);
}
}
but no luck. With the static approach, works fine:
MouseArea
{
anchors.fill: parent
onClicked: {
myCarModel.appendRowFromQml(car_1);
}
}
Is there a way to dynamically create a C++
object from the QML
side? I also couldn't use Qt.createComponent
because there is no *.qml
file in which Car
is defined, as Car
was defined in C++
.
Upvotes: 7
Views: 5355
Reputation: 1030
Actually all qml objects are dynamically allocated. In your case Car
has also. Loader
and other alternatives are just for directing it over qml. So if you like to pass a qml object on C++ side, the only thing you need to have a slot/invokable function with Car * parameter. In your slot/invokable function, you must specify that you are taking the objects ownership to qml engine.
Suppose you have a Car class something similar like this,
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;
};
And a Store class similar to this,
class Store : public QObject {
Q_OBJECT
public:
explicit Store(QObject *parent = Q_NULLPTR);
Q_INVOKABLE void sell(Car *car);
};
And if you pass your Car object to Store object on qml,
Car {
id: car1
name: "H1"
}
MouseArea {
anchors.fill: parent
onClicked: Store.sell(car1);
}
then you must to specify the object ownership in your sell function,
void Store::sell(Car *car)
{
qDebug() << car->name() << "just sold!!";
QQmlEngine::setObjectOwnership(car, QQmlEngine::CppOwnership);
delete car; // proof of the car is dynamically allocated
}
Upvotes: 1
Reputation: 7170
As I said in the comments, the problem is the variable component
, which doesn't exist at that time.
So to fix the problem it is enough to replace the following code:
onClicked: {
component = Qt.createQmlObject(...);
by:
onClicked: {
var component = Qt.createQmlObject(...);
Upvotes: 2
Reputation: 59
You can use a Loader .
Something like this:
Loader {
id: carLoader
active: false
sourceComponent:
Car {
id : car_1
carName : "H1"
carBrand : "Hummer"
carPrice : 125000
}
MouseArea
{
anchors.fill: parent
onClicked: carLoader.active:true
}
Upvotes: 2