PyQt连接到KeyPressEvent

14

某些小部件将允许我执行:

self.widget.clicked.connect(on_click)

但是做:

self.widget.keyPressEvent.connect(on_key)

如果对象没有属性'connect',将会失败。

我知道子类化widget并重新实现keyPressEvent方法将使我能够响应该事件。但是之后如何.connect()到键盘事件,或者换句话说,从用户上下文中如何做?


请纠正我如果我错了,但keyPressEvent不是一个slot,所以它不能被连接。您必须使用任何事件处理程序来处理它。 - f.rodrigues
2个回答

19

创建一个自定义信号,并从您重新实现的事件处理程序中发出它:

class MyWidget(QtGui.QWidget):
    keyPressed = QtCore.pyqtSignal(int)

    def keyPressEvent(self, event):
        super(MyWidget, self).keyPressEvent(event)
        self.keyPressed.emit(event.key())
...

def on_key(key):
    # test for a specific key
    if key == QtCore.Qt.Key_Return:
        print('return key pressed')
    else:
        print('key pressed: %i' % key)

self.widget.keyPressed.connect(on_key)

(注意:为了保留已有的事件处理方式,调用基类实现是必需的。)


1
你不需要覆盖 __init__ 并调用父类的 __init__ 吗? - wesanyer
1
@wesanyer。不论是否被重写,Python总是会自动调用每个基类的__init__方法。但是如果您确实重写了__init__,那么您还需要显式地调用基类的实现(因为它将不再被自动调用)。 - ekhumoro
1
在这个上下文中,on_key是什么? - Szabolcs Dombi
@DombiSzabolcs。当信号被发射时,会调用一个插槽。在PyQt/PySide中,插槽可以是任何Python可调用对象。 - ekhumoro

6

我过去处理这个问题的方法是(这是一个解决办法),在发送方中声明/连接信号,在接收方中也声明/连接信号。

def keyPressEvent(self, event):
    if type(event) == QtGui.QKeyEvent:
        if event.key() == QtCore.Qt.Key_Space:
            self.emit(QtCore.SIGNAL('MYSIGNAL'))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接