强制 QItemDelegate 重绘

Posted

技术标签:

【中文标题】强制 QItemDelegate 重绘【英文标题】:Force QItemDelegate to repaint 【发布时间】:2018-03-05 21:15:45 【问题描述】:

我目前正在尝试让自定义委托通过外部按钮更改它正在绘制的颜色。我目前的工作原理是按钮会改变委托绘制的颜色,但委托不会在按下按钮时更新,而是在我将鼠标移到关联的查看器上时更新。

我为颜色目的制作了一个自定义按钮(非常简单)

class ColorButton(QPushButton):
    def __init__(self,parent=None,color=None):
        super(ColorButton,self).__init__(parent)
        self.color=color

    def paintEvent(self,e):
        painter=QPainter()
        painter.begin(self)
        painter.fillRect(self.rect(),self.color)
        painter.end()

    def getColor(self):
        return self.color

然后我将颜色按钮的pressed() 信号连接到我的委托的updateBG 函数。

button1=ColorButton(color=QColor(0,0,0))
button1.pressed.connect(delegate.updateBG)

委托的 updateBG() 函数只是更新自身内部的一个颜色变量。

def updateBG(self):
    color=self.sender().getColor()
    self.bgBrush=QBrush(color)

我的paint()函数在绘制矩形时只使用这种颜色。

def paint(self,painter,option,index):
    painter.save()
    painter.setBrush(self.bgBrush)
    painter.drawRect(self.rect())
    painter.restore()

有没有办法强制委托重绘? update() 和 repaint() 函数都不适用于委托本身。我是否必须在查看器(即 QListView)上调用 repaint()?如果这是唯一的方法,有没有办法从代表内部获得观众?还是应该将此 updateBG() 函数移到委托类之外?

我通过 QT.py 使用 QT5(实际上是 pyside2 或 PyQt5)。

【问题讨论】:

我认为推荐的方法是将信息(在本例中为颜色)存储在模型中(例如在自定义用户角色中)。然后,当您更新模型时,应在模型和视图之间触发相关信号以重绘适当的部分(前提是您的绘图代码从模型中读取值!)。 这可能会起作用,但会非常冗余。颜色变化是对代理如何绘制所有模型项的更全局描述。如果我将它存储在模型中,我将不得不使用新颜色更新内部的每个条目,这似乎比仅更新委托中的单个变量效率低。不过,我确实找到了一种手动更新的方法。 哦,我明白了。我没有意识到它是一种全球(或接近全球)的颜色。在这种情况下,您可能想要使用样式表。我很确定您可以从 paint 方法访问该信息,并且在样式表更新时会调用它。 【参考方案1】:

发现我可以通过将 press() 信号连接到查看器的重置功能来强制更新。

button1.pressed.connect(viewer.reset)

不确定这是否是最好的方法,但它似乎有效。

【讨论】:

以上是关于强制 QItemDelegate 重绘的主要内容,如果未能解决你的问题,请参考以下文章

QPlainTextEdit 强制重绘

SwiftUI 强制子视图重绘

从 PaintCode 强制自定义 NSView 重绘

如何强制刷新/重绘 JScrollPane?

Delphi VCL 强制菜单重绘

如何在 NSScrollView 中强制重绘内容