Qt Quick ListView access to delegate item
-
Hello,
i want to write a timer application with QuickControls and QML, the user should be able to add dynamic Start Times. I use a ListView, where the User can append TextFields with the Start Time. How can I get the values of the dynamic created TextFields, so i can use them to control my timer for example the Values from the TextField with the id textMin from the code below?
Or is there a better way to do this?Thanks in advance
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Listview") property int number: 0 RowLayout{ id:row Button { id: button1 text: qsTr("Create Textfield") width: (parent.width / 5)*2 height: 50 onClicked: { listModel.append({current: "text " + (++number)}) } } Button { id: button2 text: qsTr("Get Text") width: (parent.width / 5)*2 height: 50 onClicked: { //get the Text from the Textfield with textMin //not working? console.log(listView1.childAt(1).textMin.text) } } } ListView { id: listView1 anchors.top: row.bottom anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right delegate: Item { id: item anchors.left: parent.left anchors.right: parent.right height: 160 ColumnLayout{ Label{ text:"Start-Time " + (index+1) } RowLayout{ Label{ text: "Min: " } TextField{ id: textMin } } RowLayout{ Label{ text: "Sec: " } TextField{ id: textSec } } } } model: ListModel { id: listModel } } }
-
@ht1723 Delegate objects shouldn't usually be used from outside that object itself. You can add a button to the delegate and update the model with listModel.setProperty(index...) or do something else when it's clicked.
In theory you can add to the delegate:
Connections { target: button2 onClicked: { console.log("click received in", index) } }
but this works only if the proper delegate item is visible (i.e. inside the view area) at that moment, and all the visible delegate items will catch that signal. This is because the delegate items are created dynamically when the view sees it fit and usually it has only the visible items (plus couple of extra before and after) existing at each moment, and this is also the reason why you shouldn't access the delegate items from outer objects.
However, the ListView has the currentItem property which keeps the current delegate item. You can set the currentIndex and then get the current item. In your example:
Button { id: button1 onClicked: { listModel.append({current: "text " + (++number)}) listView1.currentIndex = listView1.count-1 } //etc. } Button { id: button2 onClicked: { console.log(listView1.currentItem.text) } //etc. } delegate: Item { property alias text: textMin.text //etc.
If you have only few items in the view you could also consider using a Repeater which has all the items existing all the time. There you can use itemAt(index).