【问题标题】:How to paint on top of QListWidget in eventfilter in PyQt4/PySide?如何在 PyQt4/PySide 的 eventfilter 中的 QListWidget 上绘制?
【发布时间】:2017-01-28 18:25:57
【问题描述】:

我在 QLable 上试过这个并且它有效,我不想子类化小部件,因为它们是在 .ui 文件中定义的,我只需要做简单的修改,所以我想避免委托。如果我把我的代码放在paintEvent中它可以工作,但为什么我不能把它放在eventfilter中?

它似乎画了正方形,但它在 listWidgetItem 区域下方。

# -*- coding: utf-8 -*-
from PySide.QtCore import *
from PySide.QtGui import *

class xxxx(QListWidget):
    def __init__(self, parent=None):
        super(xxxx, self).__init__(parent)
        self.installEventFilter(self)

    # def paintEvent(self, event):
    #     p = QPainter()
    #     p.begin(self.viewport())
    #     p.setPen(QPen(Qt.black))
    #     p.fillRect(QRect(0, 1, 20, 20), Qt.red)
    #     p.end()

    def eventFilter(self, widget, event):
        if event.type() == QEvent.Paint:
            p = QPainter()
            # p.begin(self.viewport())
            p.begin(widget)
            p.setPen(QPen(Qt.red))
            p.fillRect(QRect(0, 1, 20, 20), Qt.red)
            p.end()
            return True
        return QListWidget.eventFilter(self, widget, event)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    view = xxxx()
    view.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyside qpainter qlistwidget


    【解决方案1】:

    您需要在视口上安装事件过滤器:

    class xxxx(QListWidget):
        def __init__(self, parent=None):
            super(xxxx, self).__init__(parent)
            self.viewport().installEventFilter(self)
    
        def eventFilter(self, widget, event):
            if event.type() == QEvent.Paint and widget is self.viewport():
                p = QPainter()
                p.begin(widget)
                p.setPen(QPen(Qt.red))
                p.fillRect(QRect(0, 1, 20, 20), Qt.red)
                p.end()
                return True
            return super(xxxx, self).eventFilter(widget, event)
    

    【讨论】:

    • 为什么是 return super.... 而不是简单的 false ?不会错误地向上传播
    • @qrtLs 因为您必须遵守基类实现的返回值 - 可以是 TrueFalse。 (将有几十种不同的事件类型通过此过滤器,而不仅仅是绘制事件)。
    • 确实很荣幸,但是真/假还可以,但是为什么return super(xxxx, self).eventFilter(widget, event)(==不应该被尊重==假,对吧?)
    • @qrtLs 严格来说,OP 事件过滤器不正确,因为它不检查事件与哪个对象相关。这与他们的问题并不真正相关,但我现在修改了我的答案来解决它。必须始终调用基类实现,以便正确处理所有对象的所有事件。 OPs 示例实际上并没有在任何其他对象上安装事件过滤器,但原则仍然适用,因为其中一个基类可能已经这样做了。
    • 所以 return False 是可以的,意味着事件被吃掉了,我确信没有其他用户安装的事件过滤器被注册,它也可能处理它。否则我需要超级......等等。
    猜你喜欢
    • 1970-01-01
    • 2018-01-20
    • 2018-11-20
    • 2016-05-05
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    相关资源
    最近更新 更多