当小部件失去焦点时,我如何拦截

2024-05-23 18:08:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个QPlainTextEdit,希望在内容失去焦点时处理它。我已经看到我可以用focusChanged事件或focusOutEvent虚函数来实现这一点。在

我不知道如何用新语法传递参数(即my_app.focusChanged.connect(my_handler),其中my_handler是一个本地定义的函数)。所以我试着用虚拟函数。在

由于接口是用QT Designer创建的,继承QPlainTextEdit会有点过头,所以我试图通过简单地使用my_text_edit.focusOutEvent = my_handler覆盖虚函数。这确实截获了我想要的消息,但它显然覆盖了QPlainTextEdit中的一些内置功能,我得到了一些伪制品——即文本编辑中的光标在失去焦点时不会消失。我想我应该以某种方式称之为最初的活动,对我有用的是:

在我的__init__方法中,我有:

    self.original_handler = self.my_text_edit.focusOutEvent
    self.my_text_edit.focusOutEvent = self.my_handler

my_handler的定义是:

^{pr2}$

我基本上是在复制我希望图书馆为我做的事情。我觉得这太笨拙了,我知道在维护期间,它会在许多方面产生反作用。有人能提出一个更简洁的方法吗?谢谢!在


Tags: 方法函数textself内容定义my语法
1条回答
网友
1楼 · 发布于 2024-05-23 18:08:45

就个人而言,我从来没有使用过重写虚拟方法的monkey-patching风格,但是保留原始行为的正确方法是直接调用基类方法,如下所示:

def my_handler(self, event):
    QtGui.QPlainTextEdit.focusOutEvent(self.my_text_edit, event)
    # my own handling follows...

不过,我不明白为什么不能使用focusChanged信号。它的处理程序是:

^{pr2}$

但是,我个人倾向于使用event filter

class Window(QtGui.QMainWindow)
    def __init__(self):
        ...
        self.my_text_edit.installEventFilter(self)

    def eventFilter(self, source, event):
        if (event.type() == QtCore.QEvent.FocusOut and
            source is self.my_text_edit):
            print('eventFilter: focus out')
            # return true here to bypass default behaviour
        return super(Window, self).eventFilter(source, event)

这是一个更加灵活的解决方案,它提供了一种通用的方法来处理通过Qt设计器导入的任何小部件的任何event type(或者,实际上,任何您不想子类化的小部件)。在

还有一种可能性是widget promotion,它可以用来直接用自己的子类替换生成的ui模块中的小部件。这样您就可以通过继承覆盖任何虚拟方法,而不是对单个实例进行猴子修补。如果您要从Qt Designer导入多个相同类型的小部件,这些小部件共享许多自定义功能,那么这可以提供一个非常干净的解决方案。在

关于如何在PyQt中进行小部件升级的简单解释可以在我的回答中找到:Replace QWidget objects at runtime。在

相关问题 更多 >