ItemDelegate忽略stylesh

2024-10-02 14:29:08 发布

您现在位置:Python中文网/ 问答频道 /正文

为什么当我使用item委托时,即使调用了super(paint)事件,样式表仍然会被忽略?你知道吗

具有子项的项应具有穿过整行的深色背景。你可以在附在第4列的图片中看到,单元格应该是深色的,但它和其他单元格一样是浅灰色的。如果禁用将项委托分配给该列的代码,它将修复视觉效果。你知道吗

enter image description here

import os, sys, pprint
from Qt import QtGui, QtWidgets, QtCore

DecorationRole2 = QtCore.Qt.UserRole + 1000

class IconDelegate(QtWidgets.QStyledItemDelegate):
    def paint(self, painter, option, index):
        super(self.__class__, self).paint(painter, option, index)
        value = index.data(DecorationRole2)
        if value:
            margin = 10
            mode = QtGui.QIcon.Normal

            if not (option.state & QtWidgets.QStyle.State_Enabled):
                mode = QtGui.QIcon.Disabled
            elif option.state & QtWidgets.QStyle.State_Selected:
                mode = QtGui.QIcon.Selected

            if isinstance(value, QtGui.QPixmap):
                icon = QtGui.QIcon(value)
                option.decorationSize = value.size()

            elif isinstance(value, QtGui.QColor):
                pixmap = QtGui.QPixmap(option.decorationSize)
                pixmap.fill(value)
                icon = QtGui.QIcon(pixmap)

            elif isinstance(value, QtGui.Image):
                icon = QtGui.QIcon(QtGui.QPixmap.fromImage(value))
                option.decorationSize = value.size() / value.devicePixelRatio()

            elif isinstance(value, QtGui.QIcon):
                state =  QtGui.QIcon.On if option.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
                actualSize = option.icon.actualSize(option.decorationSize, mode, state)
                option.decorationSize = QtCore.QSize(min(option.decorationSize.width(), actualSize.width()), min(option.decorationSize.height(), actualSize.height()))

            r = QtCore.QRect(QtCore.QPoint(), option.decorationSize)
            r.moveCenter(option.rect.center())
            r.setRight(option.rect.right() - margin)
            state = QtGui.QIcon.On if option.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
            icon.paint(painter, r, QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter, mode, state)

class Window(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.resize(500, 400)

        self.uiItems = QtWidgets.QTreeView()
        self.uiItems.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.uiItems.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.uiItems.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        self.uiItems.setModel(QtGui.QStandardItemModel())
        self.uiItems.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.uiItems.setStyleSheet('''
            QAbstractItemView{
                background-color: rgb(50,50,50);
                alternate-background-color: rgb(45,45,45);
                border: 1px solid rgb(34,34,34);
                border: none;
                color: gray;
            }
            QAbstractItemView::item {
                border-right: 1px solid rgb(30,30,30);
            }
            QAbstractItemView::item:has-children, QAbstractItemView::branch:has-children {
                background: rgb(30,30,30);
                color: white;
            }
            QAbstractItemView::item:selected,
            QAbstractItemView::item:alternate:selected {
                background-color: rgba(20,130,230);
            }
            QAbstractItemView::item:hover,
            QAbstractItemView::item:alternate:hover {
                background-color: rgba(20,130,230,74);
            }
            QAbstractItemView::item:selected:hover {
                background-color: rgba(20,130,230);
            }
        ''')

        delegate = IconDelegate(self.uiItems)
        self.uiItems.setItemDelegateForColumn(2, delegate)

        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.uiItems)
        self.setLayout(self.layout)

        for i in range(3):
            parent1 = QtGui.QStandardItem('Parente Item ' + str(i))
            parent2 = QtGui.QStandardItem()
            parent3 = QtGui.QStandardItem()
            self.uiItems.model().appendRow([parent1, parent2, parent3])

            for x in range(3):
                col1 = QtGui.QStandardItem('Child Item' + str(x))
                col2 = QtGui.QStandardItem('Item' + str(x))
                col3 = QtGui.QStandardItem('Item' + str(x))
                col3.setData(self.createDotPixmap(), role=QtCore.Qt.DecorationRole)
                col3.setData(self.createRectPixmap(), role=DecorationRole2)
                parent1.appendRow([col1,col2,col3])
        self.uiItems.expandAll()

    def createRectPixmap(self, col=QtGui.QColor(240,50,50)):
        px = QtGui.QPixmap(12,12)
        px.fill(QtCore.Qt.transparent)
        pxSize = px.rect().adjusted(1,1,-1,-1)
        painter = QtGui.QPainter(px)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setBrush(col)
        painter.setPen(QtGui.QPen(QtGui.QColor(150,20,20), 1.25))
        painter.drawRect(pxSize)
        painter.end()
        return px


    def createDotPixmap(self, col=QtGui.QColor(128,128,128)):
        px = QtGui.QPixmap(12,12)
        px.fill(QtCore.Qt.transparent)
        pxSize = px.rect().adjusted(1,1,-1,-1)
        painter = QtGui.QPainter(px)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setBrush(col)
        painter.setPen(QtGui.QPen(QtGui.QColor(15,15,15), 1.25))
        painter.drawEllipse(pxSize)
        painter.end()
        return px

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = Window()
    ex.show()
    app.exec_()

Tags: selfvalueitemqtoptionstatepainterpx