Reputation: 604
I want to repeat from a string that I have in a variable.
From the documentation (and it works):
Column {
Repeater {
model: ["apples", "oranges", "pears"]
Text { text: "Data: " + modelData }
}
}
Now, I want to replace the model with a variable X, like this:
Column {
Repeater {
model: X
Text { text: "Data: " + modelData }
}
}
But it outputs nothing, no error. If I just show the content of X in a text label it shows this: ["apples", "oranges", "pears"], which is the exact content of my X variable.
So I'm not really sure how to approach it. I have to somehow make my string an object?
Using QT 5.12.6
Upvotes: 1
Views: 1115
Reputation: 25956
Firstly, contrary to your title, you can make a QML Repeater
work with a variable. The question wasn't clear on exactly what you did try, but, your use case indicates an array.
I present 3 ways of declaring a property that you can use in a Repeater
:
property var fruitArrayQt5: ["apples", "oranges", "pears"]
property list<string> fruitArrayQt6: ["apples", "oranges", "pears"]
ListModel {
id: fruitModel
ListElement { name: "apples" }
ListElement { name: "oranges" }
ListElement { name: "pears" }
}
In the case of fruitArrayQt5
the property is declared as a var
. Which, unfortunately, means subsequent changes to the array (e.g. via push/remove/etc) will not be signaled and the Repeater
will not react to changes. The workaround is you have to keep reassigning the Repeater
's model
.
In the case of fruitArrayQt6
the property is declared as a list<string>
. Because it is using the new Qt6 list
primitive, it means subsequent changes to the array (e.g. via push/remove) WILL be signaled to the Repeater
. It requires Qt6, possibly Qt6.4 to use this.
In the case of fruitModel
changes done to the ListModel
(e.g. via append/remove) WILL also be signal to the Repeater
.
In the following example, we populate three Repeaters
demonstrating the 3 types above. When you click on the Add
button you see that the Repeater
s only reacts to changes done to fruitArrayQt6 and fruitModel. The Repeater
attached to fruitArrayQt5 doesn't react to changes. You have to enable the Workaround
check box to force an update to Repeater
's model property:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
property var fruitArrayQt5: ["apples", "oranges", "pears"]
property list<string> fruitArrayQt6: ["apples", "oranges", "pears"]
ListModel {
id: fruitModel
ListElement { name: "apples" }
ListElement { name: "oranges" }
ListElement { name: "pears" }
}
RowLayout {
width: parent.width
ColumnLayout {
Layout.alignment: Qt.AlignTop
Repeater {
model: fruitModel
Text { text: "fruitModel: " + name }
}
}
ColumnLayout {
Layout.alignment: Qt.AlignTop
Repeater {
id: arrayRepeater
model: fruitArrayQt5
Text { text: "fruitArrayQt5: " + modelData }
}
}
ColumnLayout {
Layout.alignment: Qt.AlignTop
Repeater {
model: fruitArrayQt6
Text { text: "fruitArrayQt6: " + modelData }
}
}
}
footer: Frame {
RowLayout {
CheckBox {
id: workaround
text: qsTr("Workaround")
}
Button {
text: qsTr("Add")
onClicked: {
fruitModel.append({name:"bananas"});
fruitArrayQt5.push("bananas");
fruitArrayQt6.push("bananas");
if (workaround.checked)
arrayRepeater.model = fruitArrayQt5;
}
}
Button {
text: qsTr("Reset")
onClicked: {
while (fruitModel.count > 3)
fruitModel.remove(fruitModel.count - 1);
while (fruitArrayQt5.length > 3)
fruitArrayQt5.pop();
while (fruitArrayQt6.length > 3)
fruitArrayQt6.pop();
if (workaround.checked)
arrayRepeater.model = fruitArrayQt5;
}
}
}
}
}
You can Try it Online!
Upvotes: 2
Reputation: 3924
From the documentation:
Property names must begin with a lower case letter and can only contain letters, numbers and underscores.
When I'm using a upper case letter like X
as the property name I get the following compile error:
error: Property names cannot begin with an upper case letter
If you use a lowercase x
it will instead use the predefined x
property of Repeater
as it inherits Item
.
If you want to make sure you get the correct x
you should use ids like so:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Window {
id: root
width: 400
height: 300
visible: true
property var x: ["apples", "oranges", "pears"]
Column {
Repeater {
model: root.x
Text { text: "Data: " + modelData }
}
}
}
As Jürgen Lutz said the type of your property is also important to know. It has to be of var
type. If you are using Qt 6.4 and above you can also use the list
type like so:
property list<string> test: ["apples", "oranges", "pears"]
Upvotes: 2