Creating a C++ defined object in QML
-
Hi all -
This is similar to, but different from, an earlier thread.
I have a QML file that accepts an argument. The argument is a C++ defined object, and may be null, depending on the use case. If it's not null, I want to make a local copy (which seems to be working). If it is null, I want to create a new instance of this object (which isn't working).
Here's the class:
class Schedule : public QObject { Q_OBJECT QML_ELEMENT public: Q_INVOKABLE explicit Schedule(QObject *parent = nullptr); Q_INVOKABLE static Schedule *cloneSchedule(Schedule *source);
And the QML file:
ColumnLayout { property Schedule schedule // sometimes null depending on caller property Schedule scheduleCopy property Schedule newSchedule: Schedule Component.onCompleted: { if (schedule !== null) { console.log("ScheduleCreateEdit.qml: creating clone of Schedule in list.") scheduleCopy = schedule.cloneSchedule(schedule) } else { console.log("ScheduleCreateEdit.qml: creating new Schedule.") // nothing I've tried here works; it's always null. scheduleCopy = new Schedule//newSchedule//schedule.cloneSchedule(newSchedule) } }
How do I correctly code the creation of a new instance of this class?
Thanks...
-
@Bob64 I tried this, and it seems to work:
ColumnLayout { id: scheduleCreate property Schedule schedule property Schedule scheduleCopy Schedule { id: newSchedule } Component.onCompleted: { if (schedule !== null) { scheduleCopy = schedule.cloneSchedule(schedule) } else { scheduleCopy = newSchedule.cloneSchedule(newSchedule) }
If I understand your suggestion, it would be more like this:
Component { id: scheduleComponent Schedule { id: newSchedule } } property Schedule scheduleCopy Component.onCompleted: { if (schedule !== null) { scheduleCopy = schedule.cloneSchedule(schedule) } else { scheduleCopy = scheduleComponent.createObject(*** what goes in here? ***)
Right? So, what are the arguments to createObject() in this case?
Thanks...
@mzimmers I think it's the parent as the first argument and then an optional JS object argument of any properties you want to initialise it with.
Something like:
scheduleComponent.createObject(scheduleCreate, {"prop1": prop1Val, "prop2": prop2Val, ...})
I don't know if that's the correct parent for your case and of course you might not want to set any initial properties, in which case leave out the second argument. (Edit: looking more closely at your example, you don't seem to set any properties, but I guess you might have simplified it compared with the real thing.)
-
Hi all -
This is similar to, but different from, an earlier thread.
I have a QML file that accepts an argument. The argument is a C++ defined object, and may be null, depending on the use case. If it's not null, I want to make a local copy (which seems to be working). If it is null, I want to create a new instance of this object (which isn't working).
Here's the class:
class Schedule : public QObject { Q_OBJECT QML_ELEMENT public: Q_INVOKABLE explicit Schedule(QObject *parent = nullptr); Q_INVOKABLE static Schedule *cloneSchedule(Schedule *source);
And the QML file:
ColumnLayout { property Schedule schedule // sometimes null depending on caller property Schedule scheduleCopy property Schedule newSchedule: Schedule Component.onCompleted: { if (schedule !== null) { console.log("ScheduleCreateEdit.qml: creating clone of Schedule in list.") scheduleCopy = schedule.cloneSchedule(schedule) } else { console.log("ScheduleCreateEdit.qml: creating new Schedule.") // nothing I've tried here works; it's always null. scheduleCopy = new Schedule//newSchedule//schedule.cloneSchedule(newSchedule) } }
How do I correctly code the creation of a new instance of this class?
Thanks...
@mzimmers said in Creating a C++ defined object in QML:
If it is null, I want to create a new instance of this object (which isn't working).
What will be the use of this new instance?
-
@mzimmers said in Creating a C++ defined object in QML:
If it is null, I want to create a new instance of this object (which isn't working).
What will be the use of this new instance?
@GrecKo said in Creating a C++ defined object in QML:
What will be the use of this new instance?
To serve as a template for the user to populate, and then send a command to add the new instance to the model list. It's perfectly fine if this is a temporary copy; it only exists for the user to edit.
EDIT:
It seems like all I need to do is invoke the class c'tor, but I can't figure out the correct syntax to do this in QML.
-
@GrecKo said in Creating a C++ defined object in QML:
What will be the use of this new instance?
To serve as a template for the user to populate, and then send a command to add the new instance to the model list. It's perfectly fine if this is a temporary copy; it only exists for the user to edit.
EDIT:
It seems like all I need to do is invoke the class c'tor, but I can't figure out the correct syntax to do this in QML.
@mzimmers in the simplest case you would construct a C++ object exposed to QML simply by using it as a QML object:
ColumnLayout { MyCppObject { ...} }
You want to create it dynamically though so can you do something like wrapping it in a
Component
and then usingcreateObject
to instantiate it?Component { id: myCppObjectComponent MyCppObject {} } ... var myCppObj = myCppObjectComponent.createObject(...)
-
@mzimmers in the simplest case you would construct a C++ object exposed to QML simply by using it as a QML object:
ColumnLayout { MyCppObject { ...} }
You want to create it dynamically though so can you do something like wrapping it in a
Component
and then usingcreateObject
to instantiate it?Component { id: myCppObjectComponent MyCppObject {} } ... var myCppObj = myCppObjectComponent.createObject(...)
@Bob64 I tried this, and it seems to work:
ColumnLayout { id: scheduleCreate property Schedule schedule property Schedule scheduleCopy Schedule { id: newSchedule } Component.onCompleted: { if (schedule !== null) { scheduleCopy = schedule.cloneSchedule(schedule) } else { scheduleCopy = newSchedule.cloneSchedule(newSchedule) }
If I understand your suggestion, it would be more like this:
Component { id: scheduleComponent Schedule { id: newSchedule } } property Schedule scheduleCopy Component.onCompleted: { if (schedule !== null) { scheduleCopy = schedule.cloneSchedule(schedule) } else { scheduleCopy = scheduleComponent.createObject(*** what goes in here? ***)
Right? So, what are the arguments to createObject() in this case?
Thanks...
-
@Bob64 I tried this, and it seems to work:
ColumnLayout { id: scheduleCreate property Schedule schedule property Schedule scheduleCopy Schedule { id: newSchedule } Component.onCompleted: { if (schedule !== null) { scheduleCopy = schedule.cloneSchedule(schedule) } else { scheduleCopy = newSchedule.cloneSchedule(newSchedule) }
If I understand your suggestion, it would be more like this:
Component { id: scheduleComponent Schedule { id: newSchedule } } property Schedule scheduleCopy Component.onCompleted: { if (schedule !== null) { scheduleCopy = schedule.cloneSchedule(schedule) } else { scheduleCopy = scheduleComponent.createObject(*** what goes in here? ***)
Right? So, what are the arguments to createObject() in this case?
Thanks...
@mzimmers I think it's the parent as the first argument and then an optional JS object argument of any properties you want to initialise it with.
Something like:
scheduleComponent.createObject(scheduleCreate, {"prop1": prop1Val, "prop2": prop2Val, ...})
I don't know if that's the correct parent for your case and of course you might not want to set any initial properties, in which case leave out the second argument. (Edit: looking more closely at your example, you don't seem to set any properties, but I guess you might have simplified it compared with the real thing.)
-
@mzimmers I think it's the parent as the first argument and then an optional JS object argument of any properties you want to initialise it with.
Something like:
scheduleComponent.createObject(scheduleCreate, {"prop1": prop1Val, "prop2": prop2Val, ...})
I don't know if that's the correct parent for your case and of course you might not want to set any initial properties, in which case leave out the second argument. (Edit: looking more closely at your example, you don't seem to set any properties, but I guess you might have simplified it compared with the real thing.)
@Bob64 yep, that works. I chose not to parent the object -- I believe this will cause it to be destroyed when this file goes out of scope.
property Schedule schedule property Schedule scheduleCopy Component { id: scheduleComponent Schedule { id: newSchedule } } Component.onCompleted: { if (schedule !== null) { scheduleCopy = schedule.cloneSchedule(schedule) } else { scheduleCopy = scheduleComponent.createObject() } }
Thanks for the help.
-
M mzimmers has marked this topic as solved on
-
M mzimmers referenced this topic on