【发布时间】:2012-02-28 22:03:15
【问题描述】:
我做了一个快速的示例程序来演示这个问题
import sys
from PyQt4 import QtGui
from PyQt4.QtCore import Qt
class AWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(AWindow, self).__init__(parent=parent)
self.setCentralWidget(QtGui.QWidget())
self.centralWidget().setLayout(QtGui.QFormLayout())
self.centralWidget().layout().addRow(
QtGui.QLabel('some text'),
QtGui.QLineEdit()
)
self.centralWidget().layout().addRow(
QtGui.QLabel('some text'),
QtGui.QCheckBox('this is checkbox')
)
def keyPressEvent(self, e):
if int(e.modifiers()) == (Qt.ControlModifier+Qt.AltModifier):
if e.key() == Qt.Key_K:
#when ctrl+alt+k is pressed, a message box should open
msg = QtGui.QMessageBox(
QtGui.QMessageBox.Information,
'w00t',
'You pressed ctrl+alt+k'
)
msg.exec_()
def main():
app = QtGui.QApplication(sys.argv)
w = AWindow()
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
问题
在此示例中,我正在捕获 ctrl+alt+k 键盘快捷键。问题是,如果文本输入小部件在按下这些键时具有键盘焦点,则 keyPressEevent 处理程序不会捕获它,而是在框中键入大写字母 K。 (这与所有 ctrl+alt 按键相同)。
如果另一种小部件获得焦点,即不接受文本输入的小部件(例如复选框、按钮),则按键将按应有的方式注册,并且在示例中,将显示消息框。
此外,仅使用 Ctrl 修饰符的键盘快捷键也可以正常工作。
这个问题只出现在 Windows 上,而不是在 Linux 上,所以这让我相信这与 windows 如何处理 ctrl+alt 修饰符有关,或者我可能没有正确捕获修饰符。
有没有办法解决这个问题?
编辑
我从 Spidey 的评论中得出了这个解决方案。
我继承了 QLineEdit 并像这样处理它的 keyPressEvent 。
#EDIT: this doesn't work, see below
def keyPressEvent(self, e):
if e.modifiers() and Qt.ControlModifier and Qt.AltModifier:
e.ignore()
super(CoolLineEdit, self).keyPressEvent(e)
再次编辑
将修饰符添加为整数并在 e.ignore() 之后返回(也许不需要忽略)似乎非常重要。
这是真正的解决方案。
def keyPressEvent(self, e):
if int(e.modifiers()) == (QtCore.Qt.ControlModifier+QtCore.Qt.AltModifier):
e.ignore()
return
super(SaveLineEdit, self).keyPressEvent(e)
【问题讨论】:
-
我不确定,但 AFAIK 事件是从小部件树的底部处理的,因此 QLineEdit 小部件在 QMainWindow 之前捕获它是很自然的。
-
是的。就是这样。我尝试将 lineedit 子类化并在那里捕获 keyPressEvent ,我想我可能已经解决了(参见 OP 中的编辑)。仍然奇怪的是,在 Windows 上 ctrl+alt 的处理方式就像 shift 一样,现在当我在寻找时,我在其他 Qt 应用程序中也注意到了它。
-
很高兴看到您提出了这个建议 - 见下文,在您发表评论前一分钟 :)