PyQt 不识别箭头键

5 投票
1 回答
13216 浏览
提问于 2025-04-18 18:08

我正在尝试写一个非常简单的PyQt应用程序,想让用户可以用方向键来导航,而不是点击按钮。

我已经实现了一些基本功能,在我的主QWidget中,我重写了keyPressEvent方法,现在我只是想让它弹出一个提示框(QMessageBox.information(self, "Hey", "pressed:{}".format(event), QMessageBox.Ok))。

这个功能对标准的ASCII键(比如字母和回车键)都能正常工作,但当我按下方向键时,它完全没有反应,我实在搞不清楚为什么。

我在想,可能是因为我用的是没有数字键盘的笔记本电脑(这是台HP的普通ASCII键盘,四个方向键在右侧Shift键下面,没有数字键盘)。

有没有什么建议或帮助?如果需要的话我可以发代码,但因为keyPressEvent对其他所有键都有效,所以我不确定发代码有什么用。

1 个回答

6

如果你想让子部件不被关注,而只关注主 QWidget,你可以设置子部件的焦点策略为“无焦点”。

下面是一个例子,希望能帮到你:

import sys
from PyQt4 import QtGui, QtCore

class QCustomWidget (QtGui.QWidget):
    def __init__ (self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        myQLayout = QtGui.QVBoxLayout()
        self.my1QPushButton = QtGui.QPushButton('Test 1', self)
        self.my2QPushButton = QtGui.QPushButton('Test 2', self)
        self.setChildrenFocusPolicy(QtCore.Qt.NoFocus)
        myQLayout.addWidget(self.my1QPushButton)
        myQLayout.addWidget(self.my2QPushButton)
        self.setLayout(myQLayout)

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

    def keyPressEvent (self, eventQKeyEvent):
        messageQMessageBox = QtGui.QMessageBox(QtGui.QMessageBox.Question, 'Question', 'Hello Main', QtGui.QMessageBox.Yes)
        messageQMessageBox.exec_()
        QtGui.QWidget.keyPressEvent(self, eventQKeyEvent)

appQApplication = QtGui.QApplication(sys.argv)
windowQCustomWidget = QCustomWidget()
windowQCustomWidget.setFixedSize(640, 480)
windowQCustomWidget.show()
sys.exit(appQApplication.exec_())

QWidget.setFocusPolicy (self, Qt.FocusPolicy policy) 参考

焦点策略枚举参考


在部件中,当前光标的位置会影响按键的响应。

情况1:纯 QWidget:在这种情况下,它可以跟踪所有按键,因为焦点在这个 QWidget 上。

import sys
from PyQt4 import QtGui, QtCore

class QCustomWidget (QtGui.QWidget):
    def __init__ (self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        myQLayout = QtGui.QVBoxLayout()
        self.setLayout(myQLayout)

    def keyPressEvent (self, eventQKeyEvent):
        messageQMessageBox = QtGui.QMessageBox(QtGui.QMessageBox.Question, 'Question', 'Hello', QtGui.QMessageBox.Yes)
        messageQMessageBox.exec_()
        QtGui.QWidget.keyPressEvent(self, eventQKeyEvent)

appQApplication = QtGui.QApplication(sys.argv)
windowQCustomWidget = QCustomWidget()
windowQCustomWidget.setFixedSize(640, 480)
windowQCustomWidget.show()
sys.exit(appQApplication.exec_())

情况2:在 QWidget 中添加按钮:在这种情况下,无法跟踪方向键,因为焦点在按钮上,方向键被用来设置新的焦点位置。(如果你在Linux上使用Windows风格,你可以看到焦点的网格线)

import sys
from PyQt4 import QtGui, QtCore

class QCustomWidget (QtGui.QWidget):
    def __init__ (self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        myQLayout = QtGui.QVBoxLayout()
        self.my1QPushButton = QtGui.QPushButton('Test 1', self)
        self.my2QPushButton = QtGui.QPushButton('Test 2', self)
        myQLayout.addWidget(self.my1QPushButton)
        myQLayout.addWidget(self.my2QPushButton)
        self.my1QPushButton.keyPressEvent = self.button1KeyPressEvent
        self.my2QPushButton.keyPressEvent = self.button2KeyPressEvent
        self.setLayout(myQLayout)

    def keyPressEvent (self, eventQKeyEvent):
        messageQMessageBox = QtGui.QMessageBox(QtGui.QMessageBox.Question, 'Question', 'Hello Main', QtGui.QMessageBox.Yes)
        messageQMessageBox.exec_()
        QtGui.QWidget.keyPressEvent(self, eventQKeyEvent)

    def button1KeyPressEvent (self, eventQKeyEvent):
        messageQMessageBox = QtGui.QMessageBox(QtGui.QMessageBox.Question, 'Question', 'Hello Button 1', QtGui.QMessageBox.Yes)
        messageQMessageBox.exec_()
        QtGui.QPushButton.keyPressEvent(self.my1QPushButton, eventQKeyEvent)

    def button2KeyPressEvent (self, eventQKeyEvent):
        messageQMessageBox = QtGui.QMessageBox(QtGui.QMessageBox.Question, 'Question', 'Hello Button 2', QtGui.QMessageBox.Yes)
        messageQMessageBox.exec_()
        QtGui.QPushButton.keyPressEvent(self.my2QPushButton, eventQKeyEvent)

appQApplication = QtGui.QApplication(sys.argv)
windowQCustomWidget = QCustomWidget()
windowQCustomWidget.setFixedSize(640, 480)
windowQCustomWidget.show()
sys.exit(appQApplication.exec_())

我不知道PyQt返回的方向键的ASCII码是什么,但你可以避免这个问题。在PyQt中有一个 QtCore.Qt.Key 的枚举,你可以查看这个类的参考资料。

例子:

def keyPressEvent (self, eventQKeyEvent):
    key = eventQKeyEvent.key()
    if key == QtCore.Qt.Key_F1:
        print 'Help'
    elif key == QtCore.Qt.Key_F5:
        print 'Reload'
    elif key == QtCore.Qt.Key_Left:
        print 'Left'
    elif key == QtCore.Qt.Key_Up:
        print 'Up'
    elif key == QtCore.Qt.Key_Right:
        print 'Right'
    elif key == QtCore.Qt.Key_Down:
        print 'Down'

另见:Qt.Key 枚举参考

撰写回答