How to implement checkstate for QAbstractItemModel or QAbstractListModel



  • Hello, I have success implementing some methods of QAbstractListModel. How can I add checkstate to the listed items in the model. The model is used by QListView.

    #include "intmodel.h"
    
    IntModel::IntModel(int count,  QObject *parent) : QAbstractListModel(parent)
    {
        for (int i=0; i < count; ++i)
            m_values << i+1;
    }
    
    int IntModel::rowCount(const QModelIndex &parent) const
    {
        if (parent.isValid())
            return 0;
        return  m_values.count();
    }
    
    QVariant IntModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
    
        if(role != Qt::DisplayRole && role != Qt::CheckStateRole) {// && role != Qt::EditRole )
            return QVariant();
        }
    
        if((role == Qt::DisplayRole) && (index.column() == 0 && index.row() < m_values.count()))
            return m_values.at( index.row() );
        else
            return QVariant();
    
    }
    
    Qt::ItemFlags IntModel::flags( const QModelIndex &index ) const
    {
        if(!index.isValid())
            return Qt::ItemIsEnabled;
        return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
    }
    
    bool IntModel::setData( const QModelIndex &index, const QVariant &value, int role )
    {
        qDebug() << "IntModel setData: " << role;
        if((role != Qt::EditRole && role != Qt::CheckStateRole) || index.column() != 0 || index.row() >= m_values.count())
            return false;
    
        if(role == Qt::EditRole) {
            if(value.toInt() == m_values.at( index.row()))
                return false;
            m_values[index.row()] = value.toInt();
            emit dataChanged(index, index);
            return true;
        }
        else if (role == Qt::CheckStateRole) {
    		// TO DO
        }
    }
    
    
    #ifndef INTMODEL_H
    #define INTMODEL_H
    
    #include <QAbstractListModel>
    #include <QDebug>
    
    class IntModel : public QAbstractListModel
    {
        Q_OBJECT
    
    public:
        explicit IntModel(int count, QObject *parent = nullptr);
    
        // Basic functionality:
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    
        Qt::ItemFlags flags(const QModelIndex &index) const override;
        bool setData(const QModelIndex &index, const QVariant &value, int role) override;
    private:
        QList<int> m_values;
    };
    
    #endif // INTMODEL_H
    
    

  • Moderators



  • @raven-worx . Thanks for your response. Yes I have seen this example. I would like to implement it without the need for Item class? But I do not know if it is possible?


  • Moderators

    @milan
    well you need to store the checkstate along with your model data/entries. There is no way around.

    For example instead of a QList<int> you could use a QList<QPair<int,Qt::CheckState> > for example, or any other custom struct (instead of QPair)



  • @raven-worx . Thanks. Is it possible to use QList<QStandardItem> instead? or QList<QVariant> or neither?


  • Moderators

    @milan said in How to implement checkstate for QAbstractItemModel or QAbstractListModel:

    Is it possible to use QList<QStandardItem> instead?

    doesn't make much sense.

    @milan:

    or QList<QVariant> or neither?

    since a QVariant can hold any type of data yes, if you like so.
    But still you will need to create a custom struct, register it's metatype and put it into a QVariant.



  • @raven-worx. I tried with example you mentioned at http://programmingexamples.net/wiki/Qt/ModelView/AbstractTableModelCheckable. But I found, I cannot hide the checkboxes (if needed). Maybe I plan to use this model for other different views too. Maybe another Listview without checkboxes.



  • @milan said in How to implement checkstate for QAbstractItemModel or QAbstractListModel:

    I cannot hide the checkboxes

    if you return QVariant() for the CheckStateRole the checkbox will not appear in the default delegate (QStyledItemDelegate)


Log in to reply