如何在QtQuick2中正确实现可检查的ListView?

问题描述:

来自C++我不知道如何在QtQuick中正确实现可检查的ListView。如何在QtQuick2中正确实现可检查的ListView?

出于测试目的,我创建了一个小测试应用程序。

型号:

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没有被调用。

什么是在QtQuick2中实现可检查ListView的正确方法?

ListView { 
    anchors.fill: parent 

    model: __myModel 

    delegate: CheckDelegate { 
     text: model.display 
     checked: model.checkState 
    } 
} 

的问题确实是该CheckDelegate不会自动调用setData。 你必须告诉它这样做。为此,您可以使用toggled signal

delegate: CheckDelegate { 
    text: model.display 
    checked: model.checkState 
    onToggled: model.checkState = checked // this will call setData for CheckStateRole 
} 
+0

我很失望设为Qml,QtQuick的......我曾很长一段时间与在我没有确定这样的事情QtWidgets ...只要设置标志,就足以让视图...我觉得QtQuick永远不会取代Widgets!很好的答案! –