我想从ListView
中选择多个项目。在C++
我会做这样的事情
if (clicked_card->is_selected) {
clicked_card->is_selected = false;
int i = 0;
while(selected_cards[i] != clicked_card) i++;
selected_cards.erase(selected_cards.begin() + i);
} else {
clicked_card->is_selected = true;
selected_cards.push_back(clicked_card);
}
上面的代码使用指针进行比较。那么如何在QML
中进行这样的选择。我提出的解决方案是这样的
Card.qml
Image {
id: delegate
property bool isSelected: false
...
MouseArea {
onClicked: {
if(isSelected === true) {
isSelected = false;
gameScene.deselectCard(selectSeq);
}
else {
isSelected = true;
gameScene.selectCard({'opParam': opParam, 'selectSeq': selectSeq});
}
}
}
}
GameScene.qml
Item {
id: gameScene
property var selectedCards: []
signal selectCard(variant userData)
onSelectCard: {
gameScene.selectedCards.push(userData)
}
signal deselectCard(variant userData)
onDeselectCard: {
for (var i = 0; i < gameScene.selectedCards.length; i += 1) {
if (gameScene.selectedCards[i].selectSeq == userData) {
gameScene.selectedCards.splice(i, 1);
break;
}
}
}
}
上面代码的问题在于我将属性isSelected
存储在由系统创建和销毁的委托中。所以这给了我错误的解决方案。有没有更好的多重选择方法或解决方案的任何改进?我通过继承model
来使用C ++中的QAbstractListModel
。
答案 0 :(得分:3)
我在Qt
文档中找到了答案。我只需要使用[DelegateModel][1]
。它具有group
属性,对于DelegateModel
中定义的每个组,将向每个委托项添加两个附加属性。表单DelegateModel.in*GroupName*
中的第一个表示项目是否属于该组,第二个DelegateModel.*groupName*Index
包含该组中项目的索引。
import QtQuick 2.0
import QtQml.Models 2.2
Rectangle {
width: 200; height: 100
DelegateModel {
id: visualModel
model: ListModel {
ListElement { name: "Apple" }
ListElement { name: "Orange" }
}
groups: [
DelegateModelGroup { name: "selected" }
]
delegate: Rectangle {
id: item
height: 25
width: 200
Text {
text: {
var text = "Name: " + name
if (item.DelegateModel.inSelected)
text += " (" + item.DelegateModel.selectedIndex + ")"
return text;
}
}
MouseArea {
anchors.fill: parent
onClicked: item.DelegateModel.inSelected = !item.DelegateModel.inSelected
}
}
}
ListView {
anchors.fill: parent
model: visualModel
}
}
其他解决方案是将属性isSelected
移动到C ++数据模型,并使用getter和setter函数更新更改。
答案 1 :(得分:0)
一个简单的解决方案。使用QPair或QPair存储所有项目的状态。
typedef QPair<int, bool> ItemState;
在列表中启用多项选择:
ui->tableView->setSelectionMode(QAbstractItemView::MultiSelection);
当你想选择一个集合时,试试这样的事情:
QList<ItemState> collection;
foreach (ItemState& el , collection) {
const int row = el.first;
const bool state = el.second;
const QModelIndex& index = ui->tableView->model()->index(row, 0);
ui->tableView->selectionModel()->select(index, state ? QItemSelectionModel::Select : QItemSelectionModel::Deselect );
}
每次修改模型中的数据时,都应该更新收集数据(添加,移除移动元素)。当用户点击卡片时,只需处理单击的事件并修改收集项目状态,然后调用循环。