PyQt:如何在子类化的QWidget中接收键盘事件?

1 投票
4 回答
7060 浏览
提问于 2025-04-16 18:15

可能这个问题已经被问过很多次了,但我找不到解决办法。

我有一个对话框:

class PostDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.ui = Ui_Dialog() #code from designer!!
        self.ui.setupUi(self)

        self.ui.plainTextEdit = ContentEditor()

这个对话框里有一个来自设计器的 QPlainTextEdit。

我需要重写这个 QPlainTextEdit 的按键按下和松开的事件。

所以我创建了一个它的子类:

class ContentEditor(QtGui.QPlainTextEdit):

    def __init__(self, parent=None):
        QtGui.QPlainTextEdit.__init__(self, parent)

    def keyPressEvent(self, event):
        print "do something"

但是 ContentEditor.keyPressEvent 从来没有被调用!这是为什么呢?

4 个回答

1

也许你需要调用QWidget的setFocusPolicy方法,这样才能接收到按键事件。关于这个keyPressEvent方法的详细信息,可以查看QWidget的API文档。

This event handler, for event event, can be reimplemented in a subclass 
to receive key press events for the widget. A widget must call setFocusPolicy() 
to accept focus initially and have focus in order to receive a key press event.
2

你想要实现的功能,可以通过在Qt Designer中将QPlainTextEdit这个控件提升为你自己定义的ContentEditor类来更好地完成。
查看Qt文档
在“提升控件”对话框中:
“提升的类名”:ContentEditor
“头文件”:your_python_module_name.h

3

我建议你使用 installEventFilter 来实现这个功能:

具体的代码示例是这样的:

class PostDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.ui = Ui_Dialog() #code from designer!!
        self.ui.setupUi(self)

        self.ui.plainTextEdit.installEventFilter(self)

    def eventFilter(self, event):
        if event.type() == QtCore.QEvent.KeyPress:
            # do some stuff ...
            return True # means stop event propagation
        else:
            return QtGui.QDialog.eventFilter(self, event)

撰写回答