I am trying to create a QTreeWidget that uses a single highlight color for all but the last selection.
I am able to change ALL the colors using the setPalette from the QTreeWidget but that only applies to the QTreeWidget and not the QTreeWidgetItems. There is no setPalette on the QTreeWidgetItems
I even tried using style sheet but again it only applies to the QTreeWidget. This method is a little painful in my actual code as I have multiple columns and branches. Currently, commented out in my code
I know I need a signal but to get the selection just don't know how to highlight them differently
from PySide2 import QtCore
from PySide2 import QtWidgets
from PySide2 import QtGui
class TestDialog(QtWidgets.QDialog):
def __init__(self):
super(TestDialog, self).__init__()
self.setWindowTitle("Test Dialog")
self.setMinimumWidth(200)
self.tree = TreeWidget()
# Change all the highlighted items to the same color
# palette = QtGui.QPalette()
# palette.setColor(QtGui.QPalette.Highlight, QtGui.QColor(93, 93, 93))
# self.tree.setPalette(palette)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(self.tree)
colors = ['red', 'green', 'blue', 'purple', 'black']
parent = self.tree
for color in colors:
parent = TreeWidgetItem(parent, color)
self.tree.expandAll()
class TreeWidget(QtWidgets.QTreeWidget):
def __init__(self):
super(TreeWidget, self).__init__()
self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.setIndentation(10)
self.setColumnCount(2)
self.header().resizeSection(1, 28)
self.header().swapSections(1, 0)
self.setHeaderHidden(True)
css = """
QTreeView::item:selected
{
background-color: grey;
}
"""
# self.setStyleSheet(css)
delegate = MyDelegate(None, self)
self.setItemDelegate(delegate)
class TreeWidgetItem(QtWidgets.QTreeWidgetItem):
def __init__(self, parent, label):
super(TreeWidgetItem, self).__init__(parent)
self.setText(0, label)
self.lockBox_cb = QtWidgets.QCheckBox()
self.treeWidget().setItemWidget(self, 1, self.lockBox_cb)
class MyDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent, tree):
super(MyDelegate, self).__init__(parent)
self.tree = tree
def paint(self, painter, option, index):
column = index.column()
row = index.row()
item = self.tree.itemFromIndex(index)
currentItem = self.tree.currentItem()
brush = QtGui.QBrush(QtCore.Qt.transparent)
painter.setBrush(brush)
painter.fillRect(option.rect, brush)
if column == 0:
if option.state & QtWidgets.QStyle.State_Selected:
if id(currentItem) == id(item):
brush = QtGui.QBrush(QtGui.QColor(102, 40, 178, 255))
else:
brush = QtGui.QBrush(QtGui.QColor(226, 131, 255, 255))
option.palette.setBrush(QtGui.QPalette.Highlight, brush)
option_copy = QtWidgets.QStyleOptionViewItem(option)
option_copy.rect.setLeft(0)
option_copy.backgroundBrush = brush
self.tree.style().drawPrimitive(QtWidgets.QStyle.PE_PanelItemViewItem, option_copy, painter)
super(MyDelegate, self).paint(painter, option, index)
if __name__ == "__main__":
d = TestDialog()
d.show()
I updated the code to reflect one of my many attempts. The results have always been the same. The color does change after additional selections but partially shows the old color until I click on a different UI. Only, then does the color fills the whole row
Once the gui refreshes, the colors are correct