QTreeView Checkboxes
Solution 1
Firstly, you'll need to modify TreeItem to keep track of the checked state:
private:
...
bool checked;
and a setter and getter:
bool isChecked() const { return checked; }
void setChecked( bool set ) { checked = set; }
Now the model will need to be modified so that the view knows about the check state:
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if ( role == Qt::CheckStateRole && index.column() == 0 )
return static_cast< int >( item->isChecked() ? Qt::Checked : Qt::Unchecked );
if (role != Qt::DisplayRole)
return QVariant();
return item->data(index.column());
}
and modify the model's flags method to let views know that the model contains checkable items:
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if ( index.column() == 0 )
flags |= Qt::ItemIsUserCheckable;
return flags;
}
I think this should do it. If you want to be able to update the TreeItem check state when the user ticks and unpicks the items, then you'll need to provide the QAbstractItemModel::setData method in your TreeModel.
Solution 2
I converted the above to PyQt for my own purposes and figured I'd share.
def data(self, index, role):
if not index.isValid():
return None
item = index.internalPointer();
if role == Qt.CheckStateRole and index.column() == self.check_col:
return int( Qt.Checked if item.isChecked() else Qt.Unchecked )
return super(TreeModel, self).data(index, role)
def flags(self, index):
if not index.isValid():
return None
if index.column() == self.check_col:
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
else:
flags = super(TreeModel, self).flags(index)
return flags
def setData(self, index, value, role=Qt.EditRole):
if index.column() == self.check_col:
if role == Qt.EditRole:
return False
if role == Qt.CheckStateRole:
item = self.getItem(index)
item.setChecked(value)
self.dataChanged.emit(index, index)
return True
return super(TreeModel, self).setData(index, value, role)
Solution 3
Here is another PyQt complete woking example using QStandardItemModel
:
model = QStandardItemModel()
parent_item = model.invisibleRootItem() # type: QStandardItem
for row in [
(Qt.Unchecked, 'unchecked'),
(Qt.PartiallyChecked, 'partially'),
(Qt.Checked, 'checked')
]:
checked, text = row
check_item = QStandardItem('')
check_item.setCheckable(True)
check_item.setCheckState(checked)
parent_item.appendRow([check_item, QStandardItem(text)])
treeview.setModel(model)
Btw, this should also work for any C++ applications.
Drise
I am a career C++/Qt developer, with a passion for Python programming. I recently have added C# to my experience set, and have developed full stack C# applications using WPF and Xamarin.Forms. I am an Agile advocate and Scrum leader along with a Clean Code zealot. Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.
Updated on September 04, 2020Comments
-
Drise over 3 years
I know this has been asked a bunch of times, but I cant seem to find anything relevant.
Using the simpletreemodel tutorial that comes packaged with Qt, how would I add checkboxes?
-
Drise over 12 yearsVery Cool! Exactly what I was looking for. However I found out that I should have been using the TreeWidget for what I'm trying to build. Thank you so much for the post however.
-
eMPee584 almost 11 yearsNot that I could propose a better solution atm, but the boolean lacks the awesome TRISTATENESS of course. (f.e. for partly-selected folders)
-
atomSmasher about 8 yearsOld thread but is there any chance you could share the whole class?
-
Alexey Markov about 3 yearsVery old thread, but there is an example of SimpleTreeModel for PyQt: gist.github.com/zhanglongqi/6994c2bc611bacb4c68f