1
votes

I'm trying to get which keys are pressed in the mousePressEvent method of a window. I know how get some key with the keyboardModifiers method of QApplication but it only works for few keys. A piece of code to start with:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys



class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        super(SurfViewer, self).__init__()
        self.parent = parent
        self.setFixedWidth(300)
        self.setFixedHeight(100)
        self.globallayout = QVBoxLayout()
        l_a = QLabel('A')
        self.globallayout.addWidget(l_a)
        self.setLayout(self.globallayout)

    def mousePressEvent(self, event):
        if event.buttons()== Qt.RightButton :
            print('Right click')
            #Call a function which return pressed keys (whatever the key)
        if event.buttons()== Qt.LeftButton :
            print('Left click')
            if QApplication.keyboardModifiers() == Qt.ControlModifier:
                print('Ctrl')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.setWindowTitle('window')
    ex.show()
    sys.exit(app.exec_( ))

So what I miss is a method to ask for which keys are pressed, not only keys availlable with keyboardModifiers. I looked at the QKeyEvent Class but I don't know how to force its call from the mousePressEvent

update

I tried the answer of @Changlong :

Changlongfrom PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys



class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        super(SurfViewer, self).__init__()
        self.parent = parent
        self.setFixedWidth(300)
        self.setFixedHeight(100)
        self.globallayout = QVBoxLayout()
        l_a = QLabel('A')
        self.globallayout.addWidget(l_a)
        self.setLayout(self.globallayout)

        self.keys=[]

    def mousePressEvent(self, event):
        if event.buttons()== Qt.RightButton :
            print('Right click')
            self.keyPressEvent()
        if event.buttons()== Qt.LeftButton :
            print('Left click')
            if QApplication.keyboardModifiers() == Qt.ControlModifier:
                print('Ctrl')

    def keyPressEvent(self, event):
        if event.key()== Qt.Key_A :
            print('A pressed')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.setWindowTitle('window')
    ex.show()
    sys.exit(app.exec_( ))

but if I maintain the A key pressed, the keyPressEvent is continuously called. So I get :

A pressed
....
A pressed
A pressed
Right click
A pressed
....
A pressed
A pressed
1
You should listen to the QKeyEvent events and keep track of which keys are down.Giacomo Alzetta

1 Answers

2
votes

For your reference:

def keyPressEvent(self, event):
    if event.key()== Qt.Key_A :
        print('A pressed')

Hope to be helpful.

result:

$ python3 pyqtqkeyevent.py 
QWidget::setLayout: Attempting to set QLayout "" on SurfViewer "", which already has a layout
Right click
Left click
A pressed

Your code is fine when mouse right/left buttons pressed.

Update:

def mousePressEvent(self, event):
    modifierPressed = QApplication.keyboardModifiers()
    modifierName = ''
    if (modifierPressed & Qt.AltModifier) == Qt.AltModifier:
        modifierName += 'Alt '

    if (modifierPressed & Qt.ControlModifier) == Qt.ControlModifier:
        modifierName += 'Ctrl '

    if (modifierPressed & Qt.ShiftModifier) == Qt.ShiftModifier:
        modifierName += 'Shift '

    if (modifierPressed & Qt.MetaModifier) == Qt.MetaModifier:
        modifierName += 'Meta '

    if (modifierPressed & Qt.KeypadModifier) == Qt.KeypadModifier:
        modifierName += 'Keypad '

    if (modifierPressed & Qt.GroupSwitchModifier) == Qt.GroupSwitchModifier:
        modifierName += 'GroupSwitch '

    if event.buttons() == Qt.RightButton:
        print('Right Click: ',modifierName)
        #self.keyPressEvent()
    if event.buttons() == Qt.LeftButton:
        print('Left Click: ',modifierName)


def keyPressEvent(self, event):
    if event.key() == Qt.Key_A:
        print('A pressed')

def keyReleaseEvent(self, event):
    if event.key() == Qt.Key_A:
        print('A Release')

Result:

$ python3 pyqtkeymouseevent.py 
QWidget::setLayout: Attempting to set QLayout "" on SurfViewer "", which already has a layout
Left Click:  Ctrl 
Left Click:  Shift 
Left Click:  Meta 
Left Click:  
Left Click:  
Left Click:  Ctrl Shift 
Left Click:  Alt Ctrl Shift Meta 
Left Click:  Alt Meta 
Left Click:  Ctrl Meta 
Left Click:  Alt Ctrl 
Left Click:  Alt Shift 
Right Click:  
Right Click:  Alt Ctrl Shift Meta 
Right Click:  Ctrl 
Right Click:  Shift 
Right Click:  Meta 
A pressed
A Release

Is this what you want?

Single press Alt and mouse button click, do not work in my Desktop(Ubuntu Xfce), because window manager eat it as "drag window operation".