C++ QML ListView多重选择
如何在QML ListVIEW中选择几个元素并将其索引发送到C++代码?< P>我非常确信没有办法使QML ListVIEW多可选择。Qt Declarative侧重于触摸屏的使用,在纯触摸UI中没有有意义的多选方法。您可以尝试获取列表项的数据,并在奇数单击时将其存储到数组中,在偶数单击时从数组中删除列表项的数据。可以是一个简单的训练,而不是创建一个类似复选框的项目列表。执行类似操作:如果单击某个元素,将其属性设置为选中(或以您的方式命名),并在委托中设置为如果选中为真,则应以不同的格式设置。另外,将它添加到一些列表中,以使用它。我也遇到了同样的问题,我发现实现它的最佳方法是在listview中创建一个新角色。假设它是firstname并被选中。您需要同时使用oncurrentinexchanged和onClicked,因为如果您滚动,这将更改项目,但不是单击。在这两种情况下,将所选角色更改为true,或者根据需要进行调整,可能您不需要滚动选择,因此只使用onClicked。单击后,可以将所选角色更改为trueC++ QML ListView多重选择,c++,qt,listview,qml,multi-select,C++,Qt,Listview,Qml,Multi Select,如何在QML ListVIEW中选择几个元素并将其索引发送到C++代码?< P>我非常确信没有办法使QML ListVIEW多可选择。Qt Declarative侧重于触摸屏的使用,在纯触摸UI中没有有意义的多选方法。您可以尝试获取列表项的数据,并在奇数单击时将其存储到数组中,在偶数单击时从数组中删除列表项的数据。可以是一个简单的训练,而不是创建一个类似复选框的项目列表。执行类似操作:如果单击某个元素,将其属性设置为选中(或以您的方式命名),并在委托中设置为如果选中为真,则应以不同的格式设置。另
onCurrentIndexChanged:
{
mListModel.append({"firstName": newEntry,"selected":true})
}
及
然后,您可以在deligate中使用高光,这将根据选定对象的状态更改颜色
下面是一段经过测试的完整代码
//copyright: Dr. Sherif Omran
//licence: LPGL (not for commercial use)
import QtQuick 2.12
import QtQuick.Layouts 1.12
Item {
property string addnewitem:""
property int removeitemindex: -1
property string appenditemstring: ""
property int appenditemindx:-1
property int fontpoint: 20
property int radiuspoint: 14
property int spacingvalue: 0
property string delegate_color:"beige"
property string delegate_border_color:"yellowgreen"
property string highlight_color:"deeppink"
signal selectedvalueSignal (string iTemstring, string stateval)
property string sv: ""
property int indexcopy:0
id:lstmodelitem
width: parent.width
height: parent.height
ListModel {
id : mListModel
// ListElement {
// firstName : "John"
// }
}
ColumnLayout {
anchors.fill: parent
ListView{
id : mListViewId
model:mListModel
delegate :delegateId
Layout.fillWidth : true
Layout.fillHeight: true
clip: true
snapMode: ListView.SnapToItem //this stops the view at the boundary
spacing: spacingvalue
highlight: Rectangle
{
id: highlightid
width: parent.width
color: mListModel.selected==="true"?"blue":highlight_color
border.color: "beige"
z:3
opacity: 0.2
}
highlightRangeMode: ListView.StrictlyEnforceRange
highlightFollowsCurrentItem:true
onCurrentIndexChanged:
{
console.log("olistdynamic Indexchanged" + currentIndex)
mListViewId.currentIndex=currentIndex
lstmodelitem.selectedvalueSignal(currentIndex, mListModel.selected)
indexcopy=currentIndex
}
}
}
function getindex()
{
console.log("current index = " + indexcopy)
return mListViewId.currentIndex
}
function setindex(index)
{
//console.log("olistdynamic set index"+index)
mListViewId.currentIndex=index
}
function add2Item(newEntry,statev){
console.log("added item with value = " + newEntry + "state " + statev)
mListModel.append({"firstName": newEntry,"selected":statev})
}
function deleteItem(index){
mListModel.remove(index,1)
}
function appendIdem(index,valueEntry,newselectedsate)
{
console.log("append item")
mListModel.set(index,{"firstName": valueEntry,"selected":newselectedsate})
}
Component {
id : delegateId
Rectangle {
id : rectangleId
width : parent.width // Remember to specify these sizes or you'll have problems
height: textId.implicitHeight*1.2
color: selected==="true"?"blue":delegate_color
border.color: delegate_border_color
radius: radiuspoint
Text {
id : textId
anchors.centerIn: parent
text : firstName
font.pointSize: fontpoint
}
MouseArea {
anchors.fill: parent
onClicked: {
lstmodelitem.selectedvalueSignal(mListModel.firstName,mListModel.selected)
mListViewId.currentIndex=index
console.log("current index = " + index)
indexcopy=index
appendIdem(index,firstName,"true")
}
onClipChanged:
{
//console.log("a")
}
}
}
}
//if the item has been changed from null to text
onAddnewitemChanged: {
console.log("added item" + addnewitem)
add2Item(addnewitem)
}
//remove item with index
onRemoveitemindexChanged: {
console.log("remove item")
deleteItem(removeitemindex)
}
//to change the item, change the index first then the string
onAppenditemstringChanged: {
appendIdem(appenditemindx,appenditemstring)
}
}
当然,您可以自由地实现一个委托,该委托提供了一种自由选择和取消选择单个项目的机制,但实现所有必需的概念取决于您。您对multiselect Google Photos有何感受?(当然,这是6年后的事了,但仍然如此。)你是说手机应用程序,通过长按照片进入(多)选择模式?是的,这绝对是在TouchUI中实现multiselection的一种非常有意义的方法。显然,我不知道8年前我在说什么。从那以后,我基本上已经关闭了Qt,所以我不知道这在Qt Quick中的地位。根据文档:“委托会根据需要实例化,并可能随时被销毁。它们是ListView的contentItem的父对象,而不是视图本身。状态永远不应该存储在委托中。”请确保使用数据模型或其他外部源存储“selected”属性,而不是委托上的属性。@Phrogz我已经看过很多次该文档了。如果状态只对每个代理本身重要怎么办?如果外部来源不需要了解代理中的状态,我看不出有什么问题。你怎么看?@WJR现在有点老了,但由于你的问题没有得到回答:问题是,将选定状态等存储在代理中,一旦它消失,就会立即销毁,这将导致丢失该选定状态。状态需要存储在模型中,然后代理可以这样使用(和修改)它。
//copyright: Dr. Sherif Omran
//licence: LPGL (not for commercial use)
import QtQuick 2.12
import QtQuick.Layouts 1.12
Item {
property string addnewitem:""
property int removeitemindex: -1
property string appenditemstring: ""
property int appenditemindx:-1
property int fontpoint: 20
property int radiuspoint: 14
property int spacingvalue: 0
property string delegate_color:"beige"
property string delegate_border_color:"yellowgreen"
property string highlight_color:"deeppink"
signal selectedvalueSignal (string iTemstring, string stateval)
property string sv: ""
property int indexcopy:0
id:lstmodelitem
width: parent.width
height: parent.height
ListModel {
id : mListModel
// ListElement {
// firstName : "John"
// }
}
ColumnLayout {
anchors.fill: parent
ListView{
id : mListViewId
model:mListModel
delegate :delegateId
Layout.fillWidth : true
Layout.fillHeight: true
clip: true
snapMode: ListView.SnapToItem //this stops the view at the boundary
spacing: spacingvalue
highlight: Rectangle
{
id: highlightid
width: parent.width
color: mListModel.selected==="true"?"blue":highlight_color
border.color: "beige"
z:3
opacity: 0.2
}
highlightRangeMode: ListView.StrictlyEnforceRange
highlightFollowsCurrentItem:true
onCurrentIndexChanged:
{
console.log("olistdynamic Indexchanged" + currentIndex)
mListViewId.currentIndex=currentIndex
lstmodelitem.selectedvalueSignal(currentIndex, mListModel.selected)
indexcopy=currentIndex
}
}
}
function getindex()
{
console.log("current index = " + indexcopy)
return mListViewId.currentIndex
}
function setindex(index)
{
//console.log("olistdynamic set index"+index)
mListViewId.currentIndex=index
}
function add2Item(newEntry,statev){
console.log("added item with value = " + newEntry + "state " + statev)
mListModel.append({"firstName": newEntry,"selected":statev})
}
function deleteItem(index){
mListModel.remove(index,1)
}
function appendIdem(index,valueEntry,newselectedsate)
{
console.log("append item")
mListModel.set(index,{"firstName": valueEntry,"selected":newselectedsate})
}
Component {
id : delegateId
Rectangle {
id : rectangleId
width : parent.width // Remember to specify these sizes or you'll have problems
height: textId.implicitHeight*1.2
color: selected==="true"?"blue":delegate_color
border.color: delegate_border_color
radius: radiuspoint
Text {
id : textId
anchors.centerIn: parent
text : firstName
font.pointSize: fontpoint
}
MouseArea {
anchors.fill: parent
onClicked: {
lstmodelitem.selectedvalueSignal(mListModel.firstName,mListModel.selected)
mListViewId.currentIndex=index
console.log("current index = " + index)
indexcopy=index
appendIdem(index,firstName,"true")
}
onClipChanged:
{
//console.log("a")
}
}
}
}
//if the item has been changed from null to text
onAddnewitemChanged: {
console.log("added item" + addnewitem)
add2Item(addnewitem)
}
//remove item with index
onRemoveitemindexChanged: {
console.log("remove item")
deleteItem(removeitemindex)
}
//to change the item, change the index first then the string
onAppenditemstringChanged: {
appendIdem(appenditemindx,appenditemstring)
}
}