Создание фильтра события

Я пытаюсь включить клавишу 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 когда я создаю фильтр? Это не работает без него.

10
задан Pang 19 April 2016 в 00:43
поделиться

2 ответа

@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)
10
ответ дан 3 December 2019 в 23:11
поделиться

Обработка ключей уже предусмотрена в 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)

`

4
ответ дан 3 December 2019 в 23:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: