如何使用 eventfilter 和 installeventfilter 方法?

How to use eventfilter and installeventfilter methods?

我正在为桌面应用程序使用 python 3.8 和 qt5。

我想在按下 Delete 键时删除选定的 QTreeWidgetItem

我试过下面的代码,但没有用:

class EventFilter(QObject):
    def __init__(self):
        super().__init__()
        pass

    def eventFilter(self, a0: 'QObject', a1: 'QEvent') -> bool:
        if isinstance(a1, QKeyEvent) and a1.matches(QKeySequence_StandardKey=QKeySequence.Delete):
            print("event filter")
            pass
        return super().eventFilter(a0, a1)

treeWidget.installEventFilter(EventFilter())
# treeWidget.viewport().installEventFilter(EventFilter())

一些帖子说要安装在视口上,但这也不起作用。

这是我的应用程序的结构:

QMainWindow
-- QTabWidget
---- QTreeWidget

你能给我一些关于如何使用 eventfilterinstalleventfilter 或任何其他推荐方式的提示吗?

问题的原因可能是 EventFilter 对象的范围,因为没有分配给变量它会立即被消除。一个可能的解决方案是分配一个具有足够范围的变量,另一种选择是将其传递给父级,因为它是一个 QObject,在这种情况下,我将使用第二个。

import sys

from PyQt5.QtCore import QEvent, QObject, pyqtSignal
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QTreeWidget


class EventFilter(QObject):
    delete_pressed = pyqtSignal()

    def __init__(self, widget):
        super().__init__(widget)
        self._widget = widget
        self.widget.installEventFilter(self)

    @property
    def widget(self):
        return self._widget

    def eventFilter(self, obj: QObject, event: QEvent) -> bool:
        if obj is self.widget and event.type() == QEvent.KeyPress:
            if event.matches(QKeySequence.Delete):
                self.delete_pressed.emit()
        return super().eventFilter(obj, event)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        tabWidget = QTabWidget()
        self.setCentralWidget(tabWidget)
        treeWidget = QTreeWidget()
        tabWidget.addTab(treeWidget, "Tree")

        eventFilter = EventFilter(treeWidget)
        eventFilter.delete_pressed.connect(self.handle_delete_pressed)

    def handle_delete_pressed(self):
        print("delete pressed")


def main():
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

另一方面,没有必要重新发明轮子,因为已经有 QShortcuts 用于检测用户何时按下组合键

import sys

from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QShortcut,
    QTabWidget,
    QTreeWidget,
)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        tabWidget = QTabWidget()
        self.setCentralWidget(tabWidget)
        treeWidget = QTreeWidget()
        tabWidget.addTab(treeWidget, "Tree")

        shortcut = QShortcut(QKeySequence.Delete, treeWidget)
        shortcut.activated.connect(self.handle_delete_pressed)

    def handle_delete_pressed(self):
        print("delete pressed")


def main():
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()