I need to create many similar elements, that differ only by coordinates.
I learned how to create this one by one:
Repeater {
model: ListModel {
ListElement { p:100; q:100; w:50; h:50; c:"red"; o:0 }
ListElement { p:200; q:100; w:50; h:50; c:"red"; o:0 }
ListElement { p:300; q:100; w:50; h:50; c:"red"; o:0 }
ListElement { p:400; q:100; w:50; h:50; c:"red"; o:0 }
ListElement { p:500; q:100; w:50; h:50; c:"red"; o:0 }
}
delegate: Rectangle {
x: p
y: q
width: w
height: h
color: c
rotation: o
}
}
I have now come to the conclusion that it would be convenient to do this with a simple for loop, using the loop index when calculating the coordinates:
Repeater {
model: ListModel {
for ( var i = 1; i <= 5; i )
{
ListElement { p:100*i; q:100; w:50; h:50; c:"red"; o:0 }
}
}
delegate: Rectangle {
x: p
y: q
width: w
height: h
color: c
rotation: o
}
}
Unfortunately, there is a problem with loop scope, and of course I don't even expect it will work in that shape... I am trying to show only my idea in the second code.
Is there an opportunity to create ListElements like this or am I confusing two different ways of item creating?
CodePudding user response:
As mentioned above, before you start writing a program, you need to learn the basics. You can't mix QML
and Javascript
in this way. It also seems to me that ListElement
is completely out of place here.
Here's how it can be rewritten:
Repeater {
model: 5
delegate: Rectangle {
x: 100 * index
y: 100
width: 50
height: 50
color: "red"
rotation: 0
}
}
If you need more control over the data, you can change to this:
Repeater {
model: [1, 2, 3, 4, 5]
delegate: Rectangle {
x: 100 * modelData
...
}
}
CodePudding user response:
For your example, I highly recommend @folibis answer as that demonstrates the usage of index
and modelData
which both are most appropriate for your scenario.
Generally speaking, you can mix QML/Javascript, you just need more practice in knowing the correct syntax/context where you can use QML and where you can use Javascript. Also, there are legimite scenarios where you want to populate a ListModel
programmatically.
In the following demo, a ListModel
is populated programmatically in JavaScript imperatively. In fact, it is even executed after all the QML components are initialized, so, the Repeater
actually initially sees an empty ListModel
. Whilst executing the populate
function, each append
signals changes to the ListModel
which your Repeater
will acknowledge through incremental updates.
import QtQuick
import QtQuick.Controls
Page {
Repeater {
model: listModel
delegate: Rectangle {
x: p
y: q
width: w
height: h
color: c
rotation: o
}
}
ListModel {
id: listModel
function populate() {
for ( let i = 1; i <= 5; i )
{
listModel.append( { p:100*i, q:100, w:50, h:50, c:"red", o:0 } );
}
}
}
Component.onCompleted: listModel.populate()
}
You can Try it Online!