【问题标题】:Creating an event filter创建事件过滤器
【发布时间】:2010-07-22 10:50:42
【问题描述】:

我正在尝试在我的树视图中启用删除键。这是我目前所拥有的:

class delkeyFilter(QObject):
    delkeyPressed = pyqtSignal()

    def eventFilter(self,  obj,  event):
        if event.type() == QEvent.KeyPress:
            if event.key() == Qt.Key_Delete:
                self.delkeyPressed.emit()
                print 'delkey pressed'
                return True
        return False

我像这样连接eventfilter

    filter = delkeyFilter(self.dataTreeView)
    self.dataTreeView.installEventFilter(filter)

为什么我在创建过滤器时需要传递self.dataTreeview?没有它就不行。

【问题讨论】:

  • 认为(但不确定,因此不作为答案发布)如果没有父级,Python 的垃圾收集器会吃掉你的过滤器,因为安装了事件filter 不会创建引用(在 python 方面)。要验证这一点,请尝试保留对 filter 的引用(例如说 self.filter = ...),但不要传递父级。

标签: python qt events pyqt


【解决方案1】:

@balpha 是正确的。简单的答案是,如果您不传入父级或以其他方式确保 filter 实例具有实时引用,它将被垃圾收集。

PyQt 使用SIP 绑定到 Qt 的 C++ 实现。来自SIP documentation

当一个 C++ 实例被包装时,一个对应的 Python 对象被创建。 Python 对象在垃圾回收方面的行为与您所期望的一样——当它的引用计数达到零时,它就会被垃圾回收。那么相应的 C++ 实例会发生什么?显而易见的答案可能是调用了实例的析构函数。但是库 API 可能会说,当实例被传递给特定函数时,库会获得实例的所有权,即调用实例的析构函数的责任从 SIP 生成的模块转移到库。

一个实例的所有权也可能与另一个实例相关联。这意味着如果拥有的实例被销毁,则拥有的实例将自动被销毁。 SIP 会跟踪这些关系,以确保 Python 的循环垃圾收集器可以检测并打破拥有和拥有的实例之间的任何引用循环。关联被实现为拥有实例,并引用了拥有的实例。

上面的意思是,如果你将一个 Python 对象传递给一个拥有所有权的 Qt 对象,那么一切都会正常工作,即使你没有保证对特定对象的引用得到了维护。

所以,为了重申@balpha 在他的评论中所说的内容,这里有一种解决方法,适用于您不想将对象传递给构造函数的情况:

self.filter = delkeyFilter()
self.dataTreeView.installEventFilter(self.filter)

【讨论】:

    【解决方案2】:

    密钥处理已在 QAbstractItemView 中实现。你所要做的就是继承树视图,然后实现keyPressEvent

    class MyTreeView(QTreeView):
    
        delkeyPressed = pyqtSignal()
    
        def __init__(self):
            QTreeView.__init__(self)
    
        def keyPressEvent(self, event): #QKeyEvent
            if event.key() == Qt.Key_Delete:
                self.delkeyPressed.emit()
                print 'del key pressed'
    
            # pass the event up the chain or we will eat the event
            QTreeView.keyPressEvent(self, event)
    

    `

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-02
      • 2020-11-09
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 2013-11-10
      • 2014-04-06
      • 1970-01-01
      相关资源
      最近更新 更多