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++
.
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
}
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(...);
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With