[Qt-qml] Dynamically created items and properties
Jan Ekholm
jan.ekholm at smultron.net
Sun Jul 25 23:04:05 CEST 2010
Hi,
Is is a known bug that items that are created dynamically do not handle
properties properly? I create lots of items using Qt.createObject() as they
can not be defined at design time. Initially I used a Repeater to set up the
items and that worked well, the item properties were fully bound to the
Q_PROPERTY properties of the C++ objects they represented. However, you can
not dynamically destroy items created using a Repeater (or so the docs have me
believe), so something else was needed.
So, now I set up my game pieces like this:
import Qt 4.7
Item {
function createUnits (component) {
if ( component.status == Component.Ready ) {
// get all units, this is a C++ list of Unit*
var unit_list = scenario.units.units;
for ( var index = 0; index < unit_list.length; index++ ) {
// the c++ unit, a Unit*
var unit = unit_list[index]
// create a new item with the root Item as parent, see
// the "id" property
var item = component.createObject( units );
if (item == null) {
console.log( "Units.createUnits: failed to create unit" );
}
else {
// bind all properties to the C++ object
item.x = unit.x * 48 + ( unit.y % 2 ) * 24
item.y = unit.y * 36
item.source = unit.icon
item.unit_id = unit.id
}
}
}
else if (component.status == Component.Error) {
// ugh
}
}
function loadComponent () {
// load the component
var component = Qt.createComponent("Unit.qml");
// create the real items
createUnits( component );
}
Component.onCompleted: loadComponent();
id: units
}
The Unit.qml file basically contains an Image {} with a few behaviours and a
mouse area and has worked fine.
This setup works so far that the Unit items get created and the correct
initial properties are set. They show up at the right place and with the right
image loaded.
It all goes wrong when the C++ object changes, say, its position. The
dynamically created items have their x and y properties bound to these C++
properties:
Q_PROPERTY( int x READ getX NOTIFY positionChanged );
Q_PROPERTY( int y READ getY NOTIFY positionChanged );
This worked fine with the Repeater created items. The Unit items nicely
followed the C++ object's properties. However, the items created with the
above code will totally ignore any property changes. No amount of emitting
positionChanged will move the dynamic items.
So, my question is now, is this:
1. a bug in my code and I'm somehow not doing it right (lets hope for that)
2. properties in dynamic objects should not work (argh!)
3. properties in dynamic objects should work but are broken
4. a combination of the above
5. none of the above
As it is I can't get dynamic creation & destruction and properties to work at
the same time and that more or less makes my whole silly game impossible to
do. Destroying items by moving them outside the game area, hiding them etc is
just a very ugly kludge and I'd like to avoid resorting to stuff like that
until nothing else works.
[Of course, one way would be to dynamically create a QML file with all the
needed Unit items when I load the game data on the C++ side. This file would
be created before the QML side is even initialized. But this would be an
epically ugly kludge that should fall into the 12th layer of hell.]
Best regards,
Jan Ekholm
--
He says gods like to see an atheist around. Gives them something to aim at.
-- Terry Pratchett, Small Gods
More information about the Qt-qml
mailing list