3

我应该如何使用委托仅更改树项的背景颜色?

如果不在文本上绘画,我无法弄清楚如何做到这一点。换句话说,当我使用下面的代码时,颜色会绘制在文本之上。文字背景下...

def paint(self, painter, option, index):
    MyDelegate.paint(self, painter, option, index)

    painter.save()

    # set background color
    painter.setPen(QPen(Qt.NoPen))
    if self.item.is_set and option.state & QStyle.State_Selected:
        painter.setBrush(QBrush(QtGui.QColor(100, 200, 0, 200)))
    else:
        painter.setBrush(QBrush(Qt.NoBrush))

    painter.drawRect(option.rect)

    painter.restore()

我想尽可能多地继承。

...

关于评论,我尝试应用答案“将颜色设置为 QTableView 行”......但我似乎无法让它在 Python 中工作。我不确定 optionV4.backgroundBrush() 的效果如何。该选项是否通过引用使用,以便应该在没有返回值的情况下使用此更改?

(这些在没有覆盖的情况下使用paint

def initStyleOption(self, option, index):
    print("initStyleOption...")
    MyBaseDelegate.initStyleOption(self, option, index)

    optionV4 = QtGui.QStyleOptionViewItemV4(option)
    optionV4.backgroundBrush = QBrush(QtGui.QColor(100, 200, 100, 200))

我也试过这个:

def initStyleOption(self, option, index):
    MyBaseDelegate.initStyleOption(self, option, index)
    option.backgroundBrush = QBrush(QtGui.QColor(100, 200, 100, 200))

...和这个:

def initStyleOption(self, option, index):
    option.backgroundBrush = QBrush(QtGui.QColor(100, 200, 100, 200))
    MyBaseDelegate.initStyleOption(self, option, index)

根据文档,这不应该返回任何东西,所以我假设选项是通过引用传递的,这是有道理的。

我找到了另一个例子,它有效(虽然我没有试图理解它)

def paint(self, painter, option, index):
    option = QtGui.QStyleOptionViewItemV4(option)  # Needed for "widget"
    self.initStyleOption(option, index)  # <--- I did not override this

    option.backgroundBrush = QBrush(QtGui.QColor(100, 200, 100, 200))
    option.widget.style().drawControl(QStyle.CE_ItemViewItem, option, painter)

    ColumnBaseDelegate.paint(self, painter, option, index)

...但是背景颜色被选择颜色覆盖。由于我试图在选择项目时更改背景颜色,所以这是一个问题。是否有不同的画笔或方法来处理选择颜色?我需要某些类型的物品是不同的颜色。

我尝试了在绘制我自己的背景之前演示反转选择状态的答案,但由于某种原因它为我绘制了一个空背景。把它涂在油漆上虽然有效......

def paint(self, painter, option, index):

    if option.state & QStyle.State_Selected:
        option.state &= ~QStyle.State_Selected  # Invert state

        # This "cast", which is needed to get option.widget, seems to be
        #   needed for backgroundBrush as well.
        option = QtGui.QStyleOptionViewItemV4(option)  # Cast for widget
        option.backgroundBrush = QBrush(QColor(100, 200, 100, 200))

        option.widget.style().drawControl(QStyle.CE_ItemViewItem, option, painter)

    super(MyDelegate, self).paint(painter, option, index)

我不明白为什么,所以我现在不会将它添加到答案中。

4

1 回答 1

4

要覆盖所选项目的背景颜色,您可以禁用initStyleOption. 例如:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class SelectionColorDelegate(QStyledItemDelegate):
        def __init__(self, parent):
        super(SelectionColorDelegate, self).__init__(parent)

    def initStyleOption(self, option, index):
        # let the base class initStyleOption fill option with the default values
        super(SelectionColorDelegate,self).initStyleOption(option, index)
        # override what you need to change in option
        if option.state & QStyle.State_Selected:
            option.state &= ~ QStyle.State_Selected
            option.backgroundBrush = QBrush(QColor(100, 200, 100, 200))

if __name__ == "__main__":
    app = QApplication(sys.argv)    
    treeWidget = QTreeWidget()
    treeWidget.setColumnCount(2)
    for i in range(5):
        item = QTreeWidgetItem(["Item %d"%i, "data" ])
        treeWidget.addTopLevelItem(item)
        for j in range(3):
            subItem = QTreeWidgetItem(["SubItem %d, %d"%(i,j), "subdata"])
            item.addChild(subItem)
        treeWidget.expandItem(item)

    treeWidget.setItemDelegate(SelectionColorDelegate(treeWidget))    
    treeWidget.show()   

    app.exec_()
    sys.exit()

显然,背景也是在调用QTreeView.drawRow委托paint函数之前绘制的,因此对于缩进的项目,该背景的一部分保持默认颜色。

于 2012-06-09T01:31:36.373 回答