我正在尝试在树视图中启用删除键。这就是我到目前为止所做的:
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
?没有它就行不通。
答案 0 :(得分:10)
@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)
答案 1 :(得分:4)