Элемент QListView с поведением выбора флажка
Я добавляю элементы-флажки в список.
Затем, когда я меняю индикатор флажка, строка элемента не выделяется. И когда я выбираю элемент в списке, индикатор флажка не изменится.
Индикатор флажка должен быть выбран / снят с выбора в строке выбора элемента, а выбор индикатора флажка должен установить выбранную строку элемента.
Начало просмотра списка:
QListView *poListView = new QListView(this);
// Create list view item model
QStandardItemModel* poModel =
new QStandardItemModel(poListView);
QStandardItem *poListItem = new QStandardItem;
// Checkable item
poListItem->setCheckable( true );
// Uncheck the item
poListItem->setCheckState(Qt::Unchecked);
// Save checke state
poListItem->setData(Qt::Unchecked, Qt::CheckStateRole);
poModel->setItem(0, poListItem);
poListView->setModel(poModel);
Любое предложение?
2 ответа
Решил эту проблему путем соединения двух сигналов
- Зарегистрированный элемент модели изменил сигнал для обработки изменения индикатора флажка.
- Активированный сигнал зарегистрированного элемента просмотра для изменения состояния индикатора флажка
Вот мой код:
void MyClass:Init()
{
m_poListView = new QListView(this);
// Set single selection mode
m_poListView->setSelectionMode(
QAbstractItemView::SingleSelection);
// Create list view item model
QStandardItemModel* poModel =
new QStandardItemModel(m_poListView);
QStandardItem * poListItem =
new QStandardItem;
// Checkable item
poListItem->setCheckable( true );
// Save checke state
poListItem->setData(Qt::Unchecked, Qt::CheckStateRole);
poModel->setItem(0, poListItem);
m_poListView->setModel(poModel);
// Register model item changed signal
connect(poModel, SIGNAL(itemChanged(QStandardItem*)),
this, SLOT (SlotItemChanged(QStandardItem*)));
// Resister view item acticated
connect( m_poListView , SIGNAL(activated(const QModelIndex & )),
this, SLOT(SlotListItemActivated(const QModelIndex & )))
}
Реализация слотов:
void MyClass::SlotItemChanged(QStandardItem *poItem)
{
// Get current index from item
const QModelIndex oCurrentIndex =
poItemChanged->model()->indexFromItem(poItem);
// Get list selection model
QItemSelectionModel *poSelModel =
m_poListView->selectionModel();
// Set selection
poSelModel->select(
QItemSelection(oCurrentIndex, oCurrentIndex),
QItemSelectionModel::Select | QItemSelectionModel::Current);
}
void MyClass::SlotListItemActivated(const QModelIndex &oIndex)
{
Qt::CheckState eCheckState = Qt::Unchecked;
// Get item's check state
bool bChecked =
oIndex.data(Qt::CheckStateRole).toBool();
// Item checked ?
if (bChecked == false)
eCheckState = Qt::Checked;
else
eCheckState = Qt::Unchecked;
// Get index model
// Note: I used QSortFilterProxyModel in the original code
QSortFilterProxyModel *poModel =
(QSortFilterProxyModel *)oIndex.model();
// Update model data
poModel->setData(oIndex, eCheckState, Qt::CheckStateRole);
}
Вы должны подключиться itemChanged
сигнал о QStandardItemModel
и выберите элементы вручную там.
Если вы хотите, чтобы флажок был отмечен при выборе, вам также необходимо подключиться selectionChanged
сигнал о QListView::selectionModel()
и отметьте / снимите галочки там.
Кроме того, вам не нужно вручную устанавливать Qt::CheckStageRole
,
Используя C++11 и лямбды, которые будут выглядеть так:
connect(poModel, &QStandardItemModel::itemChanged, [poListView, poModel](QStandardItem * item) {
const QModelIndex index = poModel->indexFromItem(item);
QItemSelectionModel *selModel = poListView->selectionModel();
selModel->select(QItemSelection(index, index), item->checkState() == Qt::Checked ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
});
connect(poListView->selectionModel(), &QItemSelectionModel::selectionChanged, [poModel](const QItemSelection &selected, const QItemSelection &deselected) {
for (const QModelIndex &index : selected.indexes()) {
poModel->itemFromIndex(index)->setCheckState(Qt::Checked);
}
for (const QModelIndex &index : deselected.indexes()) {
poModel->itemFromIndex(index)->setCheckState(Qt::Unchecked);
}
});
Или со старым connect
синтаксис:
void MyClass::handleCheckedChanged(QStandardItem *item) {
const QModelIndex index = item->model()->indexFromItem(item);
QItemSelectionModel *selModel = poListView->selectionModel();
selModel->select(QItemSelection(index, index), item->checkState() == Qt::Checked ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
}
void MyClass::handleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
foreach (const QModelIndex &index, selected.indexes()) {
index.model()->itemFromIndex(index)->setCheckState(Qt::Checked);
}
foreach (const QModelIndex &index, deselected.indexes()) {
index.model()->itemFromIndex(index)->setCheckState(Qt::Unchecked);
}
}
...
connect(poModel, SIGNAL(itemChanged(QStandardItem *)), this, SLOT(handleCheckedChanged(QStandardItem *)));
connect(poListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(handleSelectionChanged(QItemSelection, QItemSelection)));