如何在 QtQuick2 中正确实现可检查的 ListView? [英] How to correctly implement a checkable ListView in QtQuick2?
问题描述
来自 C++ 我不知道如何在 QtQuick 中正确实现可检查的 ListView.
Coming from C++ I dont know how to correctly implement a checkable ListView in QtQuick.
出于测试目的,我创建了一个小型测试应用程序.
For testing purposes I created a small test application.
模型:
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 项目.两者都连接到同一个模型.
On runtime I create a QListView widget and a ListView QtQuick2 item. Both are attached to the same model.
在小部件中选中/取消选中时,qml 视图会正确更新.在 qml 视图中选中/取消选中时,widget 视图不会改变!
When checking/unchecking in the widget, the qml view gets updated correctly. When checking/unchecking in the qml view, the widget view does not change!
我注意到我的 setData 没有被调用.
I noticed that my setData is not being called.
在 QtQuick2 中实现可检查 ListView 的正确方法是什么?
What is the correct way to implement a checkable ListView in QtQuick2?
ListView {
anchors.fill: parent
model: __myModel
delegate: CheckDelegate {
text: model.display
checked: model.checkState
}
}
推荐答案
问题确实在于 CheckDelegate
没有自动调用 setData
.你必须告诉它这样做.为此,您可以使用 toggled
信号 :
The problem is indeed that the CheckDelegate
doesn't call setData
automatically.
You have to tell it to do that. For this you can use the toggled
signal :
delegate: CheckDelegate {
text: model.display
checked: model.checkState
onToggled: model.checkState = checked // this will call setData for CheckStateRole
}
这篇关于如何在 QtQuick2 中正确实现可检查的 ListView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!