Как использовать QStyledItemDelegate для рисования только фона, без покрытия текста?

Как мне изменить только цвет фона моего элемента дерева с помощью делегата?

Я не смог понять, как это сделать, не рисуя поверх текста. Другими словами, когда я использую код ниже, цвет рисуется поверх текста. Текст находится на заднем плане …

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) 

И согласно документам, это не должно возвращать ничего, поэтому я предполагаю, что опция IS передана по ссылке, что имеет смысл.

Я нашел еще один пример, который работает (хотя я не пытался его понять)

 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) 

Я не понимаю, почему, поэтому я не буду добавлять его к ответу в этот момент.

One Solution collect form web for “Как использовать QStyledItemDelegate для рисования только фона, без покрытия текста?”

Чтобы переопределить цвет фона для выбранных элементов, вы можете отключить выбранный флаг в 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 делегата, поэтому для предметов с отступом часть этого фона сохраняет цвет по умолчанию.

  • Как вызвать функцию javascript из PyQT
  • Список элементов checkbox в PyQt
  • PySide: QMetaObject.connectSlotsByName испускает предупреждения «Нет соответствующего сигнала ...», но все еще работает ..?
  • Если я использую QT для Windows, мое приложение будет отлично работать на Linux / Mac / Windows?
  • Python Qt: интерактивный переопределяемый QGraphicsItem, область наведения мыши, не изменяющая размер
  • Очистить все виджеты в макете в pyqt
  • Qt.ScrollBarAsNeeded не показывает полосу прокрутки, когда это действительно необходимо
  • Qt: QPushButton блокируется дочерним процессом
  • Python - лучший язык программирования в мире.