How to set QCheckBox in QAbstractItemModel?

I have a model

class TreeModel : public QAbstractItemModel 

which I populate with instances of my TreeItem excluding column == 1 . In column 1, I 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 statuses in Qt::Checked or Qt::Unchecked , but my problem is: I cannot change them later when they are clicked (however setData is called with the corresponding index.column==1 and role==Qt::CheckStateRole ). I saw examples with ItemDelegate - only this seems to work. It's true? Should I use a 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; } 
+4
source share
4 answers

I did not understand the concept of Qt. You need to set the data in setData (the state of the storage check), and then populate the model in data () with this new value, which is returned for the checkbox, also:

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){ int i=1; checkedState_=Qt::Checked; }else{ int i=2; checkedState_=Qt::Unchecked; } 

data()

 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) { return checkedState_; } } return QVariant(); } if (role == Qt::DisplayRole) { if (index.column() != 1) { TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); return item->data(index.column()); } } return QVariant(); } emit dataChanged(index, index); return true; } emit dataChanged(index, index); return true;; 

}

+5
source

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

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

Not marked for (1,1) and marked (different from 1, 1)

Called

setData (), but then when the view queries the model for the value, you always return the same to data ()

+2
source

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

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

+1
source

Using the examples from @Trompa and @tinky_winky, I was able to create this working example because @Trompa suggested that we need to return another value or store this value and get it in our data () to get the actual state in this particular index.

 QVector<int> status; int SData::getStatus(int pos) { return status.at(pos); } void SData::setStatus(int pos,int value) { status.insert(pos, value); } QVariant STableModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role == Qt::DisplayRole) return rowList[index.row()][index.column()]; else if (role == Qt::CheckStateRole && index.column() == 0) { int status = SData::instance().getStatus(index.row()); if (status) return Qt::Checked; else return Qt::Unchecked; } else return QVariant(); } bool STableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid() /*|| role != Qt::EditRole*/) return false; if (role == Qt::CheckStateRole) { if ((Qt::CheckState)value.toInt() == Qt::Checked) { SData::instance().setStatus(index.row(),1); return true; } else { SData::instance().setStatus(index.row(), 0); return true; } } 
0
source

Source: https://habr.com/ru/post/1492682/


All Articles