I am trying to build a custom TreeWidget using a QStyledItemDelegate to draw custom checkboxes. Everything is working fine, except when I resize the TreeWidget columns. As you'll see below, when the "Age" column is moved all the way to the left, the "Name" checkbox from the first child item 'shows through' (even though all the text is properly elided and hidden).
Can anyone suggest why this is happening?
I've tried setting a size hint for the QStyledItemDelegate but this has no effect. Here is a minimum reproducible example:
import sys
from PyQt5 import QtCore, QtWidgets
class CustomTreeWidgetDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None) -> None:
super().__init__(parent)
def paint(self, painter, option, index):
options = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(options, index)
if options.widget:
style = option.widget.style()
else:
style = QtWidgets.QApplication.style()
# lets only draw checkboxes for col 0
if index.column() == 0:
item_options = QtWidgets.QStyleOptionButton()
item_options.initFrom(options.widget)
if options.checkState == QtCore.Qt.Checked:
item_options.state = (
QtWidgets.QStyle.State_On | QtWidgets.QStyle.State_Enabled
)
else:
item_options.state = (
QtWidgets.QStyle.State_Off | QtWidgets.QStyle.State_Enabled
)
item_options.rect = style.subElementRect(
QtWidgets.QStyle.SE_ViewItemCheckIndicator, options
)
QtWidgets.QApplication.style().drawControl(
QtWidgets.QStyle.CE_CheckBox, item_options, painter
)
if index.data(QtCore.Qt.DisplayRole):
rect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options)
painter.drawText(
rect,
QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter,
options.fontMetrics.elidedText(
options.text, QtCore.Qt.ElideRight, rect.width()
),
)
if __name__ == "__main__":
class MyTree(QtWidgets.QTreeWidget):
def __init__(self):
super().__init__()
self.setItemDelegate(CustomTreeWidgetDelegate())
header = self.header()
head = self.headerItem()
head.setText(0, "Name")
head.setText(1, "Age")
parent = QtWidgets.QTreeWidgetItem(self)
parent.setCheckState(0, QtCore.Qt.Unchecked)
parent.setText(0, "Jack Smith")
parent.setText(1, "30")
child = QtWidgets.QTreeWidgetItem(parent)
child.setCheckState(0, QtCore.Qt.Checked)
child.setText(0, "Jane Smith")
child.setText(1, "10")
self.expandAll()
# create pyqt5 app
App = QtWidgets.QApplication(sys.argv)
# create the instance of our Window
myTree = MyTree()
myTree.show()
# start the app
sys.exit(App.exec())
Treewidget before column resize
Treewidget after column resize