Ответ 1
@balpha верна. Простой ответ заключается в том, что если вы не передаете родительский или иным образом убедитесь, что экземпляр filter
имеет ссылку на живое, он будет собирать мусор.
PyQt использует SIP для привязки к реализации Qt С++. Из Документация SIP:
Когда экземпляр С++ завернут, создается соответствующий объект Python. Объект Python ведет себя так же, как и в случае сбора мусора, - это сбор мусора, когда его счетчик ссылок достигает нуля. Что же происходит с соответствующим экземпляром С++? Очевидным ответом может быть то, что вызывается деструктор экземпляров. Однако API-интерфейс библиотеки может сказать, что когда экземпляр передается определенной функции, библиотека принимает на себя ответственность за экземпляр, т.е. Ответственность за вызов экземпляра-деструктора передается из созданного модуля SIP в библиотеку.
Собственность экземпляра также может быть связана с другим экземпляром. Подразумевается, что принадлежащий ему экземпляр будет автоматически уничтожен, если экземпляр владельца будет уничтожен. SIP отслеживает эти отношения, чтобы гарантировать, что циклический сборщик мусора Pythons может обнаруживать и прерывать любые эталонные циклы между принадлежащими и принадлежащими им экземплярами. Ассоциация реализуется как экземпляр-владелец, ссылающийся на принадлежащий ему экземпляр.
Из сказанного следует, что если вы передадите объект Python объекту Qt, который будет владеть, все будет работать, даже если вы не гарантировали, что ссылка на конкретный объект была сохранена.
Итак, чтобы повторить то, что @balpha сказал в своем комментарии, здесь один способ обхода для случая, когда вы не хотите передавать объект конструктору:
self.filter = delkeyFilter()
self.dataTreeView.installEventFilter(self.filter)