Как правильно реализовать проверяемый ListView в QtQuick2?
Исходя из C++, я не знаю, как правильно реализовать проверяемый ListView в QtQuick.
Для тестирования я создал небольшое тестовое приложение.
Модель:
class MyModel : public QAbstractListModel
{
Q_OBJECT
public:
MyModel(QObject *parent = Q_NULLPTR) :
QAbstractListModel(parent)
{
for(int i = 0; i < 10; i++)
m_items.insert(QString("item%0").arg(i), qrand() % 2 == 0 ? Qt::Checked : Qt::Unchecked);
}
int rowCount(const QModelIndex& parent) const Q_DECL_OVERRIDE
{
return m_items.count();
}
QVariant data(const QModelIndex& index, int role) const Q_DECL_OVERRIDE
{
if(index.row() >= m_items.count())
return QVariant();
auto key = m_items.keys().at(index.row());
switch(role)
{
case Qt::DisplayRole:
return key;
case Qt::CheckStateRole:
return m_items[key];
}
return QVariant();
}
bool setData(const QModelIndex& index, const QVariant& value, int role) Q_DECL_OVERRIDE
{
qDebug() << "setData()" << index.row() << value << role;
switch(role)
{
case Qt::CheckStateRole:
{
auto key = m_items.keys().at(index.row());
m_items[key] = value.value<Qt::CheckState>();
emit dataChanged(index, index, QVector<int> { Qt::CheckStateRole });
return true;
}
}
return QAbstractListModel::setData(index, value, role);
}
Qt::ItemFlags flags(const QModelIndex& index) const Q_DECL_OVERRIDE
{
Qt::ItemFlags f = QAbstractListModel::flags(index);
if(index.isValid())
f |= Qt::ItemIsUserCheckable;
return f;
}
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE
{
return QHash<int, QByteArray> {
{ Qt::DisplayRole, QByteArrayLiteral("display") },
{ Qt::CheckStateRole, QByteArrayLiteral("checkState") },
};
}
private:
QMap<QString, Qt::CheckState> m_items;
};
Во время выполнения я создаю виджет QListView и элемент ListView QtQuick2. Оба прикреплены к одной модели.
При проверке / снятии отметки в виджете представление qml обновляется корректно. При установке / снятии отметки в представлении qml вид виджета не изменяется!
Я заметил, что мой setData не вызывается.
Как правильно реализовать проверяемый ListView в QtQuick2?
ListView {
anchors.fill: parent
model: __myModel
delegate: CheckDelegate {
text: model.display
checked: model.checkState
}
}
1 ответ
Решение
Проблема действительно в том, что CheckDelegate
не звонит setData
автоматически. Вы должны сказать это, чтобы сделать это. Для этого вы можете использовать toggled
сигнал:
delegate: CheckDelegate {
text: model.display
checked: model.checkState
onToggled: model.checkState = checked // this will call setData for CheckStateRole
}