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; } -
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() == 0case.bool chk = (item->getChecked() ? Qt::Unchecked : Qt::Checked); item->setChecked(chk); result = item->setData(index.column(), chk);You set the
chkyou'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 thevalueparameter 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.