通过设置焦点策略来处理方向键事件

Handle arrow key events by setting the focus policy

我想在我的应用程序中处理箭头键的按键事件。我已经读过,这样做必须禁用焦点。我遵循这个方法:PyQt not recognizing arrow keys。事实上,当在 MyApp.__init__ 中调用 self.setChildrenFocusPolicy(QtCore.Qt.NoFocus)(如链接线程和下面我的源代码中所定义)时,按下箭头键会引发一个键事件。但是,我不想在应用程序的整个运行期间保持焦点处于禁用状态,而是仅在单击按钮时保持禁用状态。所以我将 self.setChildrenFocusPolicy(QtCore.Qt.NoFocus) 移动到按钮点击功能:

def __init__(self):
    self.pushButton.clicked.connect(self.pushButtonClicked)

def pushButtonClicked(self):
    self.setChildrenFocusPolicy(QtCore.Qt.NoFocus)

确实,按下按钮会禁用焦点(例如,行编辑不能再使用文本光标)。但是,按下箭头键仍然不会引发按键事件。

整个应用程序(您需要一个带有按钮的 mainwindow.ui):

import sys
from PyQt4 import QtCore, QtGui, uic

qtCreatorFile = "d:/test/mainwindow.ui"

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

class MyApp(QtGui.QMainWindow, Ui_MainWindow):

    def setChildrenFocusPolicy(self, policy):
        def recursiveSetChildFocusPolicy (parentQWidget):
            for childQWidget in parentQWidget.findChildren(QtGui.QWidget):
                childQWidget.setFocusPolicy(policy)
                recursiveSetChildFocusPolicy(childQWidget)
        recursiveSetChildFocusPolicy(self)

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.pushButtonClicked)

    def pushButtonClicked(self):
        self.setChildrenFocusPolicy(QtCore.Qt.NoFocus)

    def keyPressEvent(self, event):
        print "a"

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

无需禁用焦点。您可以通过在应用程序上安装事件过滤器来访问所有关键事件:

class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
        ...
        QtGui.qApp.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.KeyPress:
            print(event.key())
        return super(MyApp, self).eventFilter(source, event)

但请注意,这确实一切,因此您最终可能会得到比预想的更多...