Home:ALL Converter>Ctrl+Alt key modifier behavior with Qt on windows when a textbox has focus

Ctrl+Alt key modifier behavior with Qt on windows when a textbox has focus

Ask Time:2012-02-29T06:03:15         Author:Steinthor.palsson

Json Formatter

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)            

Author:Steinthor.palsson,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/9490453/ctrlalt-key-modifier-behavior-with-qt-on-windows-when-a-textbox-has-focus
yy