2

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

Colors before GUI is refreshed

Once the gui refreshes, the colors are correct

enter image description here

Nachtwache
  • 103
  • 1
  • 9
  • I added QtWidgets.QStyledItemDelegate that allows different colors of the row but does not update correctly – Nachtwache Oct 10 '19 at 18:01
  • Never mind the space on the left side. Those are check boxes. In my real code you can see the color around the check box. That is why I setLeft option_copy to 0 to color the entire row. – Nachtwache Oct 10 '19 at 18:10
  • I do not reproduce the first image, maybe it is a theme of styles, try `app.setStyle("fusion")`, what is the output of `print(app.style().metaObject().className())`? – eyllanesc Oct 10 '19 at 19:21
  • I am using Maya's mayapy.exe as my interpreter. I failed to mentioned that. The style is QadskDarkFlatUIStyle, when running ```print self.style().metaObject().className()``` – Nachtwache Oct 10 '19 at 19:40
  • use `QApplication.instance().setStyle("fusion")`. That problem is generated by the style that Maya uses. – eyllanesc Oct 10 '19 at 19:40
  • I will look into that. But, I am unfamiliar where to set the style in my example as I am not using QApplication. I tried in the "__main__" d.setStyle('Fusion') ``` PySide2.QtWidgets.QWidget.setStyle(str) Supported signatures: PySide2.QtWidgets.QWidget.setStyle(PySide2.QtWidgets.QStyle) # ``` ```d.setStyle(QtWidgets.QStyleFactory.create('Fusion'))``` doesn't change anything – Nachtwache Oct 10 '19 at 20:06
  • use `from PySide2 import QtWidgets` `QtWidgets.QApplication.instance().setStyle("fusion")` – eyllanesc Oct 10 '19 at 20:07
  • I got the same results as my first image but with my funky white and black Maya window. Colors are still not refreshing correctly – Nachtwache Oct 10 '19 at 20:12
  • try with: `d.setStyle(QtWidgets.QStyleFactory::create("fusion"))` – eyllanesc Oct 10 '19 at 20:15
  • It didn't visible change the style and had the same off color results. – Nachtwache Oct 10 '19 at 20:21
  • Thanks for trying to help. Curious if the results are the same in a normal Python interpreter. I have to find time to install one. Then get pyqt to work. That will take some time. If anyone can confirm that would be great. – Nachtwache Oct 10 '19 at 20:39

0 Answers0