QCheckBox's not changing state?
-
Does anyone see anything wrong w/ how I'm changing the states of my QCheckBox's, rather, how they're not changing? My checkboxes appear checked, but I am unable to change them to unchecked.
QVariant MyTreeModel::data(const QModelIndex &index, int role) const { QModelIndex parent = index.parent(); QModelIndex child = index.sibling(parent.row(), parent.column()); if (!index.isValid()) return QVariant(); MyTreeItem *item = static_cast<MyTreeItem *>(index.internalPointer()); if (role == Qt::CheckStateRole) { if (parent.row() == 0 && index.column() == 0) return static_cast<int>(item->getChecked() ? Qt::Checked : Qt::Unchecked); } if (role != Qt::DisplayRole) return QVariant(); return item->data(index.column()); } bool MyTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) { QModelIndex parent = index.parent(); if (role != Qt::EditRole && role != Qt::CheckStateRole) return false; MyTreeItem *item = getItem(index); bool result; if (role == Qt::CheckStateRole) { if (parent.row() == 0 && index.column() == 0) { bool chk = (item->getChecked() ? Qt::Unchecked : Qt::Checked); item->setChecked(chk); result = item->setData(index.column(), chk); } } else result = item->setData(index.column(), value); if (result) emit dataChanged(index, index, {role}); return result; }
-
Does anyone see anything wrong w/ how I'm changing the states of my QCheckBox's, rather, how they're not changing? My checkboxes appear checked, but I am unable to change them to unchecked.
QVariant MyTreeModel::data(const QModelIndex &index, int role) const { QModelIndex parent = index.parent(); QModelIndex child = index.sibling(parent.row(), parent.column()); if (!index.isValid()) return QVariant(); MyTreeItem *item = static_cast<MyTreeItem *>(index.internalPointer()); if (role == Qt::CheckStateRole) { if (parent.row() == 0 && index.column() == 0) return static_cast<int>(item->getChecked() ? Qt::Checked : Qt::Unchecked); } if (role != Qt::DisplayRole) return QVariant(); return item->data(index.column()); } bool MyTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) { QModelIndex parent = index.parent(); if (role != Qt::EditRole && role != Qt::CheckStateRole) return false; MyTreeItem *item = getItem(index); bool result; if (role == Qt::CheckStateRole) { if (parent.row() == 0 && index.column() == 0) { bool chk = (item->getChecked() ? Qt::Unchecked : Qt::Checked); item->setChecked(chk); result = item->setData(index.column(), chk); } } else result = item->setData(index.column(), value); if (result) emit dataChanged(index, index, {role}); return result; }
@SRaD
I have no idea whether it has any relevance to your problem. But insetData()
how isresult
set to anything if it'sCheckStateRole
and you are not onrow == column == 0
? Do you not get a compiler warning for "possibly uninitialized variable used"? -
Is MyTreeItem derived from QTreeWidgetItem? If so I don't see a need to reimplement setData() at all.
-
No. MyTreeItem is just a class. I used the example just like TreeItem from here ... https://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html
And the model is derived from QAbstractItemModel.
-
No. MyTreeItem is just a class. I used the example just like TreeItem from here ... https://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html
And the model is derived from QAbstractItemModel.
@SRaD
OK, apart from what I said before which I think you ought address, your logic in yoursetData()
is wrong in therole == Qt::CheckStateRole && parent.row() == 0 && index.column() == 0
case.bool chk = (item->getChecked() ? Qt::Unchecked : Qt::Checked); item->setChecked(chk); result = item->setData(index.column(), chk);
You set the
chk
you'll use as a reverse of the currentitem->getChecked()
, i.e. it toggles each time it's called; and you pass that on tosetChecked/setData()
. But you're supposed to be using thevalue
parameter to yoursetData()
, which you're ignoring here, like you do in theelse result = item->setData(index.column(), value);
case. Your current checked/unchecked behaviour depends on how many timessetData()
happens to be called, or that it will only get called when it's time to toggle the check, both of which are quite wrong. -
@JonB
So I changed the logic to this, but I find that setData() isn't being called. The checkboxes do show up, so my model is in place, but I don't understand why this isn't called when I click on the items.bool MyTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) { QModelIndex parent = index.parent(); std::cout << "value.toInt = " << value.toInt() << std::endl; if (role != Qt::EditRole && role != Qt::CheckStateRole) return false; MyTreeItem *item = getItem(index); bool result; if (role == Qt::CheckStateRole && (parent.row() == 0 && index.column() == 0)) { Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt()); // logic probably still isn't correct here, but i'm concerned with why it's not called bool check = (state == Qt::Checked); //item->setChecked(chk); result = item->setData(index.column(), check); } else result = item->setData(index.column(), value); if (result) emit dataChanged(index, index, {role}); return result; }
-
What does your item->getChecked() look like?
And do you really store try to store the check state and the edit role in one place?
--> item->setData(index.column(), check); -
@Christian-Ehrlicher
My getChecked looks like the following:bool MyTreeItem::getChecked() const { return checked; } void MyTreeItem::setChecked(bool set) { checked = set;; }
Not sure about edit role && check state in one place. I thought if it was a checkbox, it had to be editable, and I thought setChecked() is where I needed to store it.