QML Dynamic object binding
Hello
I'm working on a project that requires creation and management of rectangles, that can be change throughout the course of time, according to some data received by a web socket.
What matters here, is that I want the QMLObjects to be fully "mirrored" in C++ classes, so we only change one object and those changes reflect to the qml rectangles.
So, according to the official QML documentation(http://doc.qt.io/qt-5/qtqml-javascri...tcreation.html), to dynamically create a rectangle I'm using this code:
Code:
function buildZone() {
var component;
var zone;
component = Qt.createComponent("Zone.qml");
zone = component.createObject(layout, {
"x": zoneMapper.x,
"y": zoneMapper.getY()+30,
"width": zoneMapper.getWidth(),
"height": zoneMapper.getHeight(),
"objectName": zoneMapper.getId(),
"color":"red"});
zoneMappers.push(zoneMapper);
}
This "zoneMapper" is an object that it is instantiated in the main.cpp of a custom class, that has x with a property as follows:
Q_PROPERTY(int x READ getX WRITE setX NOTIFY xChanged)
So when you change "x", it calls a setter in the C++ class, and everything is in sync.
Problem is, when I use a button to change zonneMapper.x, like this:
Code:
Button{
id:button1
objectName:"Button1"
text:"Button1Text"
onClicked: {
zoneMapper.x +=50;
}
}
The dynamically created rectangle doesn't move, although the "setter" and "getter" in the class are called (I can check this with breakpoints)
I noticed though, if I do this, with a static rectangle:
Code:
Rectangle{
id: staticRect
x:zoneMapper.x
y:30
width:50
height:50
color:"yellow"
}
It moves!!!
I have another problem here, regarding the "mapping" of several rectangles, but's that's stuff for another episode
So, is there a way to bind an object in C++ to a dinamically created qml object?
Thank you
Re: QML Dynamic object binding
As you want ro achieve a simple direct binding, you could try changing
Quote:
zone = component.createObject(layout, {
"x": zoneMapper.x,
"y": zoneMapper.getY()+30,[...]
into
Quote:
zone = component.createObject(layout, {
"x": Qt.binding(function() { return zoneMapper.x })
"y": Qt.binding(function() { return zoneMapper.getY()+30}),[...]
Does this work as expected?
Re: QML Dynamic object binding
Well, thank you for your reply. I solved the problem with another solution though, and now I'm to far ahead that it would be a pain to test your solution. I used the function createQmlObject which uses a string as the "builder", and, somehow, the binding is never lost.
But I have a new problem, regarding some data view model guided software.
I want to manipulate an array of "zoneMappers"
Notice the following code:
Code:
function buildZone(buildString) {
var zone;
zone = Qt.createQmlObject(buildString, layout);
zoneMappers.push(currZoneMapper);
}
The "buildString" contains a QML file as a string with a ever incrementing number (increases in main.cpp every time you call buildZone) in one of the properties that binds the C++ object to a property in qml with setContextProperty (the only way I know to share an object with qml).
The QMLObject "zone" is not even used anymore, because I want to create a unique access point to both QML and C++ in order to change the visual components.
In main I have the following code:
Code:
//zoneMapperList as a QList with several ZoneMapper instances
for(int i = 0; i< zoneMapperList.count(); i++){
engine.rootContext()->setContextProperty(zoneMapperId, zoneMapperList[i]);
engine.rootContext()->setContextProperty("currZoneMapper", zoneMapperList[i]);
zoneMapperList[i]->setViewId(zoneMapperId);
if(!QMetaObject::invokeMethod(layoutObject,
"buildZone", Q_ARG
(QVariant, zoneMapperList
[i
]->getZoneBuilderString
()) )){ zoneMapperList[i]->setViewId("");
}
else{
zoneMapperList[i]->setViewObject(layoutObject->findChild<QObject*>(zoneMapperList[i]->getViewId()));
}
}
You can see the "not so fancy" solution I used: "currZoneMapper". I use this "currZoneMapper" because I have no other way of adding a new C+ object and add it to the array.
The first string "zoneMapperID", which is something like "zoneMapper4" is used so QML gets different objects as different properties (with setContextProperty) and stores it in an array, so it can manipulate them as C+ objects.
Is there a better way to bind dynamic objects to dynamic qmlcomponents and manipulate them as one entity only?
Thank you!
Re: QML Dynamic object binding
I found a fancy solution which uses a QAbstractListModel that handles everything. This subclassed entity is bind to a repeater.
Check this thread if you want more info on this;
https://forum.qt.io/topic/82000/bind...qml-objects/25