ListView -> How to set specific item in specific position
Solved
QML and Qt Quick
-
I am trying to set specific item in center of listview, but I don't know how to do that.
Wrong item is visible. When I am trying to change first and last value, visible item is changing, but still is wrong.I tried to use currentIndex and positionViewAtIndex and it doesn't work as expected.
You can run this using
property var component_infinite: Qt.createComponent("infinite_listview/infinite_listview.qml") property var object_infinite: component_infinite.createObject(mainWindow) object_infinite.visible = true object_infinite.setValues(99, 150, 4)
// object_infinite.setValues()
import QtQuick 2.3 import QtQuick.Window 2.15 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.15 import QtQml 2.12 Item //Window { width: 30 height: 60 ListModel { id: modelID // ListElement // { // itemID: 0 // number: 0 // } } Component { id: delegateID Rectangle { id: itemDelegate height: listviewID.height/3 width: listviewID.width x: 0 y: 0 Text { horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter height: parent.height width: parent.width text: number font.pixelSize: parent.height fontSizeMode: Text.Fit } } } ListView { onCurrentItemChanged: { console.log("listviewID.currentIndex: " + listviewID.currentIndex) if(listviewID.currentIndex < (modelID.count/2)) { console.log("currentIndex <") modelID.move(modelID.count - 1, 0, 1) } if(listviewID.currentIndex > (modelID.count/2)) { console.log("currentIndex >") modelID.move(0, modelID.count - 1, 1) } } id: listviewID property var first_value: 0 property var last_value: 99 property var fill_length_value: 2 property var fill_sign_value: '0' width: parent.width height: parent.height //Ucina listview do konkretnego rozmiaru. PRzydatne, gdy uzyje sie opcji preferredHighlightBegin i preferredHighlightEnd clip: true //Ustawia ilosc widocznego listview na poczatku i na koncu. To jest dodatkowa przestrzen widoczna. PRzydaje sie, zeby elementy plynnie pojawialy sie i znikaly Dane podawane w pikselach. preferredHighlightBegin: parent.height/3 preferredHighlightEnd: parent.height/3 highlightRangeMode: ListView.StrictlyEnforceRange highlightMoveDuration: 1000 highlightMoveVelocity: -1 model: modelID delegate: delegateID Rectangle { id: current_index_border x: 0 y: parent.height/3 width: parent.width height: parent.height/3 color: "transparent" border.width: 1 } MouseArea { anchors.fill: parent onWheel: { console.log( listviewID.currentIndex ) if (wheel.angleDelta.y < 0) { console.log("W DOL 1->2") console.log(listviewID.currentIndex) var curr_index_tmp = listviewID.currentIndex if(listviewID.currentIndex < (modelID.count/2)) { modelID.move(modelID.count - 1, 0, 1) } listviewID.incrementCurrentIndex() } else if (wheel.angleDelta.y > 0) { console.log("W GORE 2->1") console.log(listviewID.currentIndex) if(listviewID.currentIndex > (modelID.count/2)) { modelID.move(0, modelID.count - 1, 1) } listviewID.decrementCurrentIndex() } } } Component.onCompleted: { } } function setValues(first = 0, last = 59, fill_length = 2, fill_value = '0') { listviewID.first_value = first listviewID.last_value = last listviewID.fill_length_value = fill_length listviewID.fill_sign_value = fill_value var sum = numberOfElements(first, last) var half1 = 0 var half2 = 0 var resultOfMod = sum % 2 if (resultOfMod === 0) { half1 = Math.floor(sum/2) } else { half1 = Math.floor(sum/2) half2 = sum - half1 } modelID.clear() var index = listviewID.last_value - half1 for (var i = (listviewID.first_value) ; i <= listviewID.last_value; i++) { console.log("index: " + index + " : i: " + i + " : listviewID.first_value: " + listviewID.first_value) if ( index <= listviewID.last_value) { modelID.append( {"itemID": index, "number": index.toString().padStart(listviewID.fill_length_value, listviewID.fill_sign_value)} ) } else { index = listviewID.first_value modelID.append( {"itemID": index, "number": index.toString().padStart(listviewID.fill_length_value, listviewID.fill_sign_value)} ) } index++ } for (var i = listviewID.first_value, index = 0 ; i <= listviewID.last_value; i++, index++) { if(modelID.get(index).itemID === 111) { listviewID.positionViewAtIndex(index, ListView.Center) break } } } function numberOfElements(a, b) { //Zwraca ilosc elementow, niezaleznie, czy pierwsza, lub ostatnia liczba jest dodatnia, lub ujemna return Math.abs(a-b) + 1 } }
I am trying to do that here. Number 111 is value which should be visible in center of listview. Other value is at startup and later, when I am trying to run setValues with values from spinbox.
for (var i = listviewID.first_value, index = 0 ; i <= listviewID.last_value; i++, index++) { if(modelID.get(index).itemID === 111) { listviewID.positionViewAtIndex(index, ListView.Center) break } }
-
I don't know how it works, but it works. If someone explain how it works, it would be nice. Below full code of control
import QtQuick 2.3 import QtQuick.Window 2.15 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.15 import QtQml 2.12 Item //Window { id: mainListView width: 30 height: 60 ListModel { id: modelID // ListElement // { // itemID: 0 // number: 0 // } } Component { id: delegateID Rectangle { id: itemDelegate height: listviewID.height/3 width: listviewID.width x: 0 y: 0 Text { horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter height: parent.height width: parent.width text: number font.pixelSize: parent.height fontSizeMode: Text.Fit } } } ListView { onCurrentItemChanged: { if(listviewID.currentIndex < (modelID.count/2)) { modelID.move(modelID.count - 1, 0, 1) } if(listviewID.currentIndex > (modelID.count/2)) { modelID.move(0, modelID.count - 1, 1) } } id: listviewID property var first_value: 0 property var last_value: 99 property var fill_length_value: 2 property var fill_sign_value: '0' width: parent.width height: parent.height //Ucina listview do konkretnego rozmiaru. PRzydatne, gdy uzyje sie opcji preferredHighlightBegin i preferredHighlightEnd clip: true //Ustawia ilosc widocznego listview na poczatku i na koncu. To jest dodatkowa przestrzen widoczna. PRzydaje sie, zeby elementy plynnie pojawialy sie i znikaly Dane podawane w pikselach. preferredHighlightBegin: parent.height/3 preferredHighlightEnd: parent.height/3 highlightRangeMode: ListView.StrictlyEnforceRange highlightMoveDuration: 1000 highlightMoveVelocity: -1 property bool set_values_first_time: false model: modelID delegate: delegateID Rectangle { id: current_index_border x: 0 y: parent.height/3 width: parent.width height: parent.height/3 color: "transparent" border.width: 1 } MouseArea { anchors.fill: parent onWheel: { console.log( listviewID.currentIndex ) if (wheel.angleDelta.y < 0) { console.log("W DOL 1->2") console.log(listviewID.currentIndex) var curr_index_tmp = listviewID.currentIndex if(listviewID.currentIndex > (modelID.count/2)) { modelID.move(0, modelID.count - 1, 1) modelID.move(0, modelID.count - 1, 1) modelID.move(0, modelID.count - 1, 1) // modelID.move(0, modelID.count - 1, 1) // modelID.move(0, modelID.count - 1, 1) listviewID.currentIndex = curr_index_tmp-3 } listviewID.incrementCurrentIndex() } else if (wheel.angleDelta.y > 0) { console.log("W GORE 2->1") console.log(listviewID.currentIndex) var curr_index_tmp = listviewID.currentIndex if(listviewID.currentIndex < (modelID.count/2)) { modelID.move(modelID.count - 1, 0, 1) modelID.move(modelID.count - 1, 0, 1) modelID.move(modelID.count - 1, 0, 1) // modelID.move(modelID.count - 1, 0, 1) // modelID.move(modelID.count - 1, 0, 1) listviewID.currentIndex = curr_index_tmp+3 } listviewID.decrementCurrentIndex() } } } Component.onCompleted: { } } function setValues(first = 0, last = 59, fill_length = 2, fill_value = '0') { listviewID.first_value = Number(first) listviewID.last_value = Number(last) listviewID.fill_length_value = Number(fill_length) listviewID.fill_sign_value = fill_value var sum = numberOfElements(listviewID.first_value, listviewID.last_value) var half1 = 0 var half2 = 0 var resultOfMod = sum % 2 if (resultOfMod === 0) { half1 = Math.floor(sum/2) } else { half1 = Math.floor(sum/2) half2 = sum - half1 } modelID.clear() for (var index_tmp = listviewID.last_value - half1, i = listviewID.first_value ; i <= listviewID.last_value; i++, index_tmp++) { console.log("index_tmp: " + index_tmp + " : i: " + i + " : listviewID.first_value: " + listviewID.first_value) if ( index_tmp <= listviewID.last_value) { modelID.append( {"itemID": index_tmp, "number": index_tmp.toString().padStart(listviewID.fill_length_value, listviewID.fill_sign_value)} ) } else { index_tmp = listviewID.first_value modelID.append( {"itemID": index_tmp, "number": index_tmp.toString().padStart(listviewID.fill_length_value, listviewID.fill_sign_value)} ) } } listviewID.currentIndex = -1 //Z tym ustaiwniem, poprawnie sie ustawia na 0, ale uzywajac scroola, przeskakuje w dzziwne miejsce for (var i = listviewID.first_value, index_tmp = 0 ; i <= listviewID.last_value; i++, index_tmp++) { if(modelID.get(index_tmp).itemID === listviewID.first_value) { listviewID.positionViewAtIndex(index_tmp, ListView.Center) if(listviewID.set_values_first_time === false) { listviewID.currentIndex = index_tmp-2 } else { listviewID.currentIndex = index_tmp } break } } listviewID.set_values_first_time = true } function numberOfElements(a, b) { //Zwraca ilosc elementow, niezaleznie, czy pierwsza, lub ostatnia liczba jest dodatnia, lub ujemna return Math.abs(a-b) + 1 } }