如何使用QStyledItemDelegate来仅绘制背景,而不覆盖文本? [英] How Do I Use a QStyledItemDelegate to Paint Only the Background, Without Covering the Text?

查看:2794
本文介绍了如何使用QStyledItemDelegate来仅绘制背景,而不覆盖文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我不能弄清楚如何在没有画画的情况下做到这一点文字顶部。换句话说,当我使用下面的代码时,颜色将被绘制在文本的顶部。文本是背景下的

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

painter.save()

#设置背景颜色
painter.setPen (QPen(Qt.NoPen))
如果self.item.is_set和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通过引用传递,这是有道理的。



我发现另一个例子,它有效(虽然我没有试图理解它)

  option = QtGui.QStyleOptionViewItemV4(选项)#需要widget
self.initStyleOption(选项,索引)#< --- I没有覆盖这个

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

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

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



我尝试了在绘制自己的背景之前反转选择状态的答案,但是它绘制了一个空的背景我有一些原因把它放在油漆中工作虽然...

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

if option.state& QStyle.State_Selected:
option.state& =〜QStyle.State_Selected#反转状态

#这个cast是获取option.widget所需的,似乎是
#需要backgroundBrush以及。
option = QtGui.QStyleOptionViewItemV4(选项)#为窗口小部件
选项.backgroundBrush = QBrush(QColor(100,200,100,200))

option.widget.style ().drawControl(QStyle.CE_ItemViewItem,选项,画家)

super(MyDelegate,self).paint(画家,选项,索引)

我不明白为什么,所以我不会在这一点上添加一个答案。

解决方案

要覆盖所选项目的背景颜色,可以在 initStyleOption 中禁用所选标志。例如:

 从PyQt4.QtCore import导入sys 
*来自PyQt4.QtGui的
import *

class SelectionColorDelegate(QStyledItemDelegate):
def __init __(self,parent):
super(SelectionColorDelegate,self).__ init __(parent)

def initStyleOption (自我,选项,索引):
#让基类initStyleOption填充选项与默认值
super(SelectionColorDelegate,self).initStyleOption(选项,索引)
#覆盖所需要的更改选项
如果option.state& QStyle.State_Selected:
option.state& =〜QStyle.State_Selected
option.backgroundBrush = QBrush(QColor(100,200,100,200))

如果__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 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 函数被调用,所以对于缩进的项目,一部分该背景保持默认颜色。


tHow should I change just the background color of my tree item using a delegate?

I haven't been able to figure out how to do this without painting on top of the text. In other words, when I use the code below, the color is drawn on top of the text. The text is under the background...

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()

I want to inherit as much as I can.

Thank you,

...

Regarding the comments, I tried to apply the answer " Set color to a QTableView row " ... but I can't seem to get it to work in Python. I'm not sure how the optionV4.backgroundBrush() as any effect. Is the option used by reference so that this change is supposed to be used without a return value?

(These are used without overriding 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))

I also tried this:

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

...and this:

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

And according to the docs, this should not return anything, so I assume option IS passed by reference, which makes sense.

I found another example, which works (though I haven't tried to understand it)

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)

...but the background color is painted over by the selection color. Since I am trying to change the background color when the item is selected, this is a problem. Is there a different brush or method for working with selection colors? I need certain types of items to be a different color.

I tried the answer which demonstrates inverting the selection state before drawing my own background, but it painted an empty background for me for some reason. Putting it in paint worked though...

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)

I don't understand why, so I won't add it to an answer at this point.

解决方案

To override background color for selected items, you can disable the selected flag in initStyleOption. For example:

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()

Apparently, the background is also painted by QTreeView.drawRow before the delegate paint function is called, so for indented items, a part of that background keeps the default color.

这篇关于如何使用QStyledItemDelegate来仅绘制背景,而不覆盖文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆