how to have a list view that take texts from more than one array then to change the color of the text and the background of the delegate according to which array they belong?
Solved
QML and Qt Quick
-
var red = ['one', 'two', 'three'] var yellow = ['four', 'five'] var green = ['six', 'seven']
mport QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.0 import "script.js" as Script Window { visible: true width: 640 height: 480 title: qsTr("List View") Rectangle { id: container width: 220 height: 300 color: 'black' anchors.centerIn: parent ListView { id: new_lv anchors.fill: parent anchors.margins: 5 clip: true model: Script.cas_total_length delegate: wordDelegate focus: true } Component { id: wordDelegate Rectangle { width: ListView.view.width height: 40 color: /////////?????? border.color: Qt.lighter(color, 1.1) Text { text: ///////////??????? height: 29 width: 50 color: ///////??????? } } } } }
-
Here you have a simple example.
The main question is how your data will be passed to the ListView and if you plan to update the entries dynamically.ApplicationWindow { width: 400 height: 680 visible: true /* DIRTY */ property var red: ['one', 'two', 'three'] property var yellow: ['four', 'five'] property var green: ['six', 'seven'] /* BETTER */ property var jsonData: [{ "text": "one", "color": "red" }, { "text": "two", "color": "red" }, { "text": "three", "color": "red" }, { "text": "four", "color": "yellow" }, { "text": "five", "color": "yellow" }, { "text": "six", "color": "green" }, { "text": "seven", "color": "green" }] /* BEST */ ListModel { id: bestModel ListElement { text: "zero" mcolor: "blue" } } // add elements to list model from JS Component.onCompleted: { for (let a in red) { bestModel.append({ "text": red[a], "mcolor": "red" }) } for (let b in yellow) { bestModel.append({ "text": yellow[b], "mcolor": "yellow" }) } for (let c in green) { bestModel.append({ "text": green[c], "mcolor": "green" }) } } RowLayout { anchors.fill: parent spacing: 20 ColumnLayout { Layout.fillHeight: true Text { text: "DIRTY" } ListView { id: dirty Layout.fillHeight: true model: red.concat(yellow).concat(green) delegate: Text { id: name text: modelData color: red.includes( modelData) ? "red" : yellow.includes( modelData) ? "yellow" : green.includes( modelData) ? "green" : "black" } } } ColumnLayout { Layout.fillHeight: true Text { text: "BETTER" } ListView { id: better Layout.fillHeight: true model: jsonData delegate: Text { text: modelData.text color: modelData.color } } } ColumnLayout { Layout.fillHeight: true Text { text: "BEST" } ListView { id: best Layout.fillHeight: true model: bestModel delegate: Text { // model. -> required because of ambiguous "text" property text: model.text // model. -> not required as "mcolor" is not ambiguous color: mcolor } } } } Button { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter text: "THREE to YELLOW" onClicked: { /* DIRTY - no auto update */ red.pop() yellow.push("three") // This would be required to update the model, but would reload all elements // dirty.model = [] // dirty.model = red.concat(yellow).concat(green) /* BETTER - no auto update */ jsonData[2].color = "yellow" // This would be required to update the model, but would reload all elements // better.model = [] // better.model = jsonData /* BEST - auto updates the single changed element */ // note index is 3, because the example above has a zero as well bestModel.setProperty(3, "mcolor", "yellow") } } }
-
aiden_- about 6 hours ago
@lemons how i can have a special highlighter (when i press arrows on keyboard) such that each array have special related highlighter color?
i tried this but it is not working.
import QtQuick 2.12 import QtQuick.Window 2.12 Window { visible: true width: 640 height: 480 title: qsTr("Y-R") property var red: ['one', 'two', 'three'] property var yellow: ['four', 'five'] property var green: ['six', 'seven'] ListModel { id: bestModel ListElement { text: "zero" mcolor: "blue" hcolor: "green" } } // add elements to list model from JS Component.onCompleted: { for (let a in red) { bestModel.append({ "text": red[a], "mcolor": "red", "hcolor": "pink" }) } for (let b in yellow) { bestModel.append({ "text": yellow[b], "mcolor": "yellow", "hcolor": "purple" }) } for (let c in green) { bestModel.append({ "text": green[c], "mcolor": "green", "hcolor": "brown" }) } } Rectangle { id: container width: 220 height: 100 color: 'black' anchors.centerIn: parent ListView { id: best model: bestModel anchors.fill: parent anchors.margins: 5 clip: true spacing: 5 focus: true delegate: Text { // model. -> required because of ambiguous "text" property text: model.text // model. -> not required as "mcolor" is not ambiguous color: mcolor } highlight: Rectangle { color: hcolor } } } }
-
@aiden_ as the highlight is not inside the delegate "loop" you can't access the model properties as inside the delegate. Therefore you could e.g. do something like this:
// read the hcolor value from the ListModel itself highlight: Rectangle { color: bestModel.get(best.currentIndex).hcolor }
also you could add a property to the delegate item and reference to this property:
delegate: Text { // property used to be accessed by currentItem of ListView property color highlightColor: hcolor // model. -> required because of ambiguous "text" property text: model.text // model. -> not required as "mcolor" is not ambiguous color: mcolor } highlight: Rectangle { color: best.currentItem.highlightColor }