2016-07-18 2 views
1

Я хочу выбрать несколько элементов из ListView. В C++ я бы сделал что-то вроде этогоВыбор нескольких элементов из ListView

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; 
      } 
     } 
    } 
} 

Проблема с вышеприведенным кодом является то, что я m сохраняет свойство isSelected в делегите, который создается и уничтожается системой. Так что это дает мне ложное решение. Есть ли лучший способ множественного выбора или каких-либо улучшений в решении? Я использую model из C++ путем подкласса QAbstractListModel.

ответ

0

Простое решение. Используйте QPair или QPair для хранения состояния всего вашего товара.

typedef QPair<int, bool> ItemState; 

Включить множественный выбор в вашем списке O таблице:

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); 
} 

Вы должны обновить свою коллекцию данные, каждый раз, когда вы изменяете данные в модели (добавьте, удалите элементы перемещения). Когда пользователь нажимает на карту, просто обрабатывайте событие с кликом и изменяйте состояние элемента коллекции и вызываете цикл.

1

Я нашел ответ в документации Qt. Мне просто нужно использовать DelegateModel. У меня есть свойство 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++ и использовать геттер и сеттер функцию, чтобы обновить изменения.

Смежные вопросы