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

发布于 2024-11-09 07:33:50 字数 710 浏览 0 评论 0原文

也许这个问题已经被问过很多次了,但我找不到解决方案。

我有一个对话框:

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 的 keyPress 和 keyRelease 。

所以我对它进行了子类化:

class ContentEditor(QtGui.QPlainTextEdit):

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

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

但 ContentEditor.keyPressEvent 从未被调用!为什么?

Maybe this is been asked many times, but i can't find a solution.

I have a dialog:

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()

This dialog has a QPlainTextEdit from the designer.

I need to override keyPress and keyRelease of that QPlainTextEdit.

So i have subclassed it:

class ContentEditor(QtGui.QPlainTextEdit):

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

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

but ContentEditor.keyPressEvent is never called! Why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏天碎花小短裙 2024-11-16 07:33:50

我建议使用 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)

I recommend using installEventFilter for this purpose:

This would look like:

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)
流殇 2024-11-16 07:33:50

您想要完成的任务最好通过在 Qt Designer 中提升将 QPlainTextEdit 小部件提升到您的子类 ContentEditor 来完成。
Qt 文档

在“升级的小部件”对话框中:
“提升班级名称”:ContentEditor
“头文件”:your_python_module_name.h

What you're trying to accomplish is better done by promoting in Qt Designer the QPlainTextEdit widget to your subclass ContentEditor.
Qt documentation

In the "Promoted Widgets" Dialog:
"Promote class name": ContentEditor
"Header file": your_python_module_name.h

〃安静 2024-11-16 07:33:50

可能您需要调用 QWidget 的 setFocusPolicy 方法来接收 KeyPress 事件。
来自 QWidget 方法 keyPressEvent

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.

May be you need to call method setFocusPolicyof QWidget to receive a KeyPress Event.
From API docs of QWidget for the method keyPressEvent:

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.
我早已燃尽 2024-11-16 07:33:50

您可能只需要交换以下两行:

self.ui.setupUi(self)
self.ui.plainTextEdit = ContentEditor()

如果您像这样编写:

self.ui.plainTextEdit = ContentEditor()
self.ui.setupUi(self)

您确保在 UI 设置之前绑定您的自定义小部件。否则,您只是替换对已初始化对象的引用。

You'll probably just need to swap the following two lines:

self.ui.setupUi(self)
self.ui.plainTextEdit = ContentEditor()

If you write it like this:

self.ui.plainTextEdit = ContentEditor()
self.ui.setupUi(self)

you make sure your custom widget gets bound before the UI gets setup. Otherwise you're just replacing a reference to an already initialised object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文