how set QCheckBox in QAbstractItemModel?

12,785

Solution 1

I didn't understand the Qt conception. You have to set data in setData() (store check state) and then populate model in data() with this new value being returned for checkbox, alike this:

setData()

bool TreeModel::setData(const QModelIndex & index, const QVariant & value, int role) {
    if (role == Qt::CheckStateRole && index.column() == 1) {
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        QTreeWidgetItem *check = static_cast<QTreeWidgetItem*>(index.internalPointer());

        if (value == Qt::Checked) {
            checkedState_ = Qt::Checked;
        }
        else {
            checkedState_ = Qt::Unchecked;
        }
    }
    emit dataChanged(index, index);
    return true;
}

data()

QVariant TreeModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid())
        return QVariant();

    if (role == Qt::CheckStateRole) {
        if (index.column() == 1) {
            return checkedState_;
        }
    }
    else if (role == Qt::DisplayRole) {
        if (index.column() != 1) {
            TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
            return item->data(index.column());
        }
    }
    return QVariant();
}  

Solution 2

It seems strange to me that you are returning always the same result for the data(CheckStateRole)

 if (role == Qt::CheckStateRole) {
            if (index.column() == 1) {
                if (index.row() == 1) {
                    return Qt::Unchecked;
                } else
                    return Qt::Checked;
            }
        }

Unchecked for (1,1) and checked for ( distinct to 1 , 1)

setData() is being called, but then, when the view queries the model for a value, you return always the same in data()

Solution 3

Without any ItemDelegate, in the flags method you must return the flag: Qt::ItemIsUserCheckable.

For more information see: http://qt-project.org/doc/qt-4.8/qt.html#ItemFlag-enum

Share:
12,785
4pie0
Author by

4pie0

&gt;&gt; p = [1 0 1]; &gt;&gt; roots(p) ans = 0.000000000000000 + 1.000000000000000i 0.000000000000000 - 1.000000000000000i

Updated on June 16, 2022

Comments

  • 4pie0
    4pie0 about 2 years

    I have a model

    class TreeModel : public QAbstractItemModel
    

    which I populate with instances of my TreeItem excluding column==1. In column 1 I've created CheckBoxes:

    QVariant TreeModel::data(const QModelIndex &index, int role) const {
        if (!index.isValid())
            return QVariant();
    
        if (role != Qt::DisplayRole) {
            if (role == Qt::CheckStateRole) {
                if (index.column() == 1) {
                    if (index.row() == 1) {
                        return Qt::Unchecked;
                    } else
                        return Qt::Checked;
                }
            }
            return QVariant();
        }
        if (role == Qt::DisplayRole) {
            if (index.column() != 1) {
                TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
                return item->data(index.column());
            }
        }
        return QVariant();
      }
    

    I can set these CheckBoxes statues to Qt::Checked or Qt::Unchecked but my problem is: I cannot change them later when they are clicked (however setData is called with appropriate index.column==1 and role==Qt::CheckStateRole). I have seen examples with ItemDelegate - only this seems to work. Is this true? Do I have to use delegate in this scenario?

    Here is my setData() function:

    bool TreeModel::setData(const QModelIndex & index, const QVariant & value,
            int role) {
        if (role==Qt::CheckStateRole && index.column() == 1) {
            TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
            QTreeWidgetItem *check = static_cast<QTreeWidgetItem*>(index.internalPointer());
    
            //if (item->data(index.column()) == Qt::Checked)
            if (value == Qt::Checked){
                int i=1;
                //check->setCheckState(1,Qt::Checked); //SIGSEGV
            }else{
                //(item->data(index.column())) = Qt::Unchecked;
                int i=2;
                //check->setCheckState(1,Qt::Unchecked);
            }
    
            emit dataChanged(index, index);
            return true;
        }
        emit dataChanged(index, index);
        return true;;
    }
    
    
    Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const {
        if (!index.isValid())
            return 0;
    
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |  Qt::ItemIsEditable;
      }