How do you use QStyledItemDelegate
/ QItemDelegate
to permanently display a complex widget, i.e. to handle the Qt.DisplayRole
, not just Qt.EditRole
?
The documentation eludes to using paint()... but that's just way to complex! Let's take for example rendering a QTreeView
or QTableVeiw
inside of a QTableView
cell.
There is QAbstractItemView.setIndexWidget()
, but that is a bad idea as it only used to display static content (and whats the fun in static models?).
I found part of the answer in another post, but it was only a small subset of the answer, so I thought it warranted a new post with proper question.
The key is to use QAbstractItemView.openPersistentEditor()
to always keep the cell in edit mode.
Qt.EditRole
flag will need to be provided for the cells which use delegates.QStyledItemDelegate.sizeHintChanged.emit(index)
needs to be called anytime the size of the editor widget has changed.QStyledItemDelegate.sizeHint()
can be tricky and tedious (or you can do index.internalPointer().editor_widget.sizeHint()
assuming you saved a reference of the editor to the internal pointer during QStyledItemDelegate.createEditor()
It should be mentioned that opening editors is costly, so if you have thousands of indexes and they are all loaded at once, it can take a while. There are many ways to mitigate this issue:
fetchMore()
mechanismopenPersistentEditor
incrementally (using a timer, or as they come into view for the first time)openPersistentEditor
when the parent is expanded and closePersistentEditor
when the parent is collapsed, and possibly restrict the use of expand-all on nodes with many children.