Создание фильтра событий - PullRequest
10 голосов
/ 22 июля 2010

Я пытаюсь включить ключ удаления в моем дереве.Это то, что у меня есть:

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 при создании фильтра?Это не работает без него.

Ответы [ 2 ]

10 голосов
/ 03 августа 2010

@ Бальфа верна. Простой ответ заключается в том, что если вы не передадите родительский элемент или иным образом не убедитесь, что экземпляр 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)
4 голосов
/ 24 июля 2010

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

`

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...