Я хотел бы добавить пользовательскую роль в QFileSystemModel (возможно, в производную модель). Я хочу использовать эту роль, чтобы сохранить состояние проверки CheckBox, которое отображается рядом с именем файла в пользовательском делегате. Как это может быть сделано?
Как добавить пользовательскую роль в QFileSystemModel
Ответы (1)
Я использовал в качестве примера Qt Quick Controls — Пример браузера файловой системы удаление части выделения.
Шаги были следующие:
Добавьте новую роль в
roleNames
:QHash<int,QByteArray> roleNames() const Q_DECL_OVERRIDE { QHash<int, QByteArray> result = QFileSystemModel::roleNames(); result.insert(SizeRole, QByteArrayLiteral("size")); result.insert(DisplayableFilePermissionsRole, QByteArrayLiteral("displayableFilePermissions")); result.insert(LastModifiedRole, QByteArrayLiteral("lastModified")); result.insert(Qt::CheckStateRole, QByteArrayLiteral("checkRole")); return result; }
Создайте контейнер, в котором хранится информация о выборе, в данном случае я буду использовать
QMap
:QMap<QPersistentModelIndex, Qt::CheckState> m_checks;
Перезапишите метод
data()
, который возвращает состояние, если оно хранится в контейнере, если оно не возвращаетсяQt::UnChecked
в качестве значения по умолчанию:QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE { if (index.isValid() && role >= SizeRole) { ... } else if (role == Qt::CheckStateRole) { QPersistentModelIndex pix(index); if(m_checks.contains(pix)){ return m_checks[pix]; } return Qt::Unchecked; } return QFileSystemModel::data(index, role); }
Перезапишите метод
setData()
, который при необходимости необходимо изменить, и создайте данные.bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole){ if(role == Qt::CheckStateRole && index.isValid()){ Qt::CheckState current = value.value<Qt::CheckState>(); if(m_checks.contains(index)){ Qt::CheckState last = m_checks[index]; if(last == current) return false; m_checks[index] = current; } else{ m_checks.insert(index, current); } emit dataChanged(index, index, {role}); return true; } return QFileSystemModel::setData(index, value, role); }
Я добавил новый столбец, в котором я установил делегата для
CheckBox
, и я использовал слотonCheckedChanged
для установки значения с использованием методаsetData()
, передаетсяQModelIndex
, данные и роль, в этом случае, проходят 10, потому что это номер значенияQt::CheckStateRole
.TreeView { id: view model: fileSystemModel ... TableViewColumn { role: "checkRole" delegate: Component { CheckBox { id: mycbx checked: styleData.value onCheckedChanged: view.model.setData(styleData.index, checked, 10) } } } ...
Полный пример можно найти по следующей ссылке.