Я пытаюсь включить клавишу Delete в своем treeview. Это - то, что я имею до сих пор:
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
когда я создаю фильтр? Это не работает без него.
@balpha правильно. Простой ответ заключается в том, что если вы не передадите родительский элемент или иным образом убедитесь, что экземпляр filter
имеет активную ссылку, он будет собран сборщиком мусора.
PyQt использует SIP для привязки к реализации Qt C ++. Из документации SIP :
Когда экземпляр C ++ упаковывается, создается соответствующий объект Python. Объект Python ведет себя так, как и следовало ожидать в отношении сборки мусора - он собирает мусор, когда его счетчик ссылок достигает нуля. Что тогда происходит с соответствующим экземпляром C ++? Очевидным ответом может быть вызов деструктора экземпляра. Однако API библиотеки может сказать, что когда экземпляр передается определенной функции, библиотека становится владельцем экземпляра, т. Е.ответственность за вызов деструктора экземпляра передается от модуля, сгенерированного SIP, в библиотеку.
Право собственности на экземпляр также может быть связано с другим экземпляром. Подразумевается, что принадлежащий экземпляр будет автоматически уничтожен, если владеющий экземпляр будет уничтожен. SIP отслеживает эти отношения, чтобы гарантировать, что циклический сборщик мусора Python может обнаруживать и прерывать любые ссылочные циклы между собственными и находящимися в собственности экземплярами. Связь реализована как экземпляр-владелец, использующий ссылку на экземпляр-владелец.
Вышеизложенное подразумевает, что если вы передадите объект Python объекту Qt, который становится владельцем, все также будет работать, даже если вы не гарантируете, что ссылка на конкретный объект сохраняется.
Итак, чтобы повторить то, что @balpha сказал в своем комментарии, вот один обходной путь для случая, когда вы не хотите передавать объект конструктору:
self.filter = delkeyFilter()
self.dataTreeView.installEventFilter(self.filter)
Обработка ключей уже предусмотрена в 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)
`