I made a quick sample program to demonstrate the problem
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()
The problem
In this sample I'm capturing the ctrl+alt+k keyboard shortcut. The problem is that if a text entry widget has keyboard focused when those keys are pressed, it is not captured by the keyPressEevent handler, instead an upper case K is typed into the box. (this is the same with all ctrl+alt keypresses).
If another kind of widget is focused, one that does not accept text input (e.g. a checkbox, button) the key press is registered as it should and in the sample, the messagebox is shown.
Also, keyboard shortcuts that use only a Ctrl modifier work fine.
This problem only presents it self on Windows, but not on Linux, so this leads me to believe this has something to do with how windows handles the ctrl+alt modifier, or perhaps I'm not capturing the modifiers properly.
Is there any way to fix this?
Edit
I derived this solution from Spidey's comment.
I sublassed the QLineEdit and handled it's keyPressEvent like this.
#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)
Edit again
Adding up the modifiers as ints and returning after e.ignore() (maybe ignore isn't needed) seems to be very important.
This is the real fix.
def keyPressEvent(self, e):
if int(e.modifiers()) == (QtCore.Qt.ControlModifier+QtCore.Qt.AltModifier):
e.ignore()
return
super(SaveLineEdit, self).keyPressEvent(e)