1

I made a ui for work using PyQt5 and Python3. Additionally to clicking the buttons, I want to execute specific actions by pressing specific keys on my keyboard e.g. the space bar. I used the following to do so:

def keyPressEvent(self, event):
    key = event.key()

    if key == Qt.Key_Space:
        print('space')
    elif key == Qt.Key_W:
        print('w')

Instead of printing 'space', it presses the focused button in the ui, when I'm pressing the space bar. Just like I hit return. Although pressing the 'W'-key prints 'w' as expected.

I already searched here at stackoverflow and other where in the web as well, but I found nothing really helpfull. The best I got was this one here. But it's using PyQt4.3 and copy and paste the code to my editor just brought me some errors. I thought the approach was a good one, but I were not able to transfer this to PyQt5.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Pandora
  • 29
  • 1
  • 4
  • It's a possibility that the space key is already bound with another listener somewhere in the interface. That could be why you're getting a different effect than you expect – Feliks Montez Jun 15 '18 at 18:28
  • @FeliksMontez Yes, I guess the my `QPushButton()` has focus and than gets pressed if I press the space bar on my keyboard. As long as no button has focus it all works as expected. I use `self.setFocus()` to set the focus on the window itself and as long as I don't click a button everything works quite fine. But if I do it get's the focus and the Problem begins. I wonder if there is a way to prevent these buttons from getting focus or at least lose it after they were clicked. This might solve my problem. – Pandora Jun 17 '18 at 19:14

2 Answers2

0

Try it:

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


class MyWindow(QWidget): 
    def __init__(self, *args): 
        QWidget.__init__(self, *args)

        # create objects
        self.la  = QLabel("Press Space or `w` in this box:")
        self.le  = MyLineEdit()
        self.la2 = QLabel("\nLook here:")
        self.le2 = QLineEdit()

        self.btnSpace = QPushButton("Button1")
        self.btnSpace.setEnabled(False)
        self.btnSpace.clicked.connect(self.onBtnSpace)
        self.btnW     = QPushButton("Button2")
        self.btnW.setEnabled(False)
        self.btnW.clicked.connect(self.onBtnW)


        # layout
        layout = QVBoxLayout()
        layout.addWidget(self.la)
        layout.addWidget(self.le)
        layout.addWidget(self.la2)
        layout.addWidget(self.le2)

        layout.addWidget(self.btnSpace)
        layout.addWidget(self.btnW)

        self.setLayout(layout)

        # connections
        #self.connect(self.le, SIGNAL("tabPressed"), self.update)
        self.le.signalTabPressed[str].connect(self.update)

    def update(self, keyPressed):
        newtext = str(self.le2.text()) + str(keyPressed)  #"tab pressed "
        self.le2.setText(newtext)

        if keyPressed == "Key Space; ":
            self.btnSpace.setEnabled(True)
            self.btnSpace.setText(str(keyPressed))

        if keyPressed == "Key W; ":
            self.btnW.setEnabled(True)
            self.btnW.setText(str(keyPressed))        


    def onBtnSpace(self):
        print("keyPressed -> btnSpace")

    def onBtnW(self):
        print("keyPressed -> btnW")       

class MyLineEdit(QLineEdit):
    signalTabPressed = pyqtSignal(str)                  # +++

    def __init__(self, *args):
        QLineEdit.__init__(self, *args)

    def event(self, event):
        #if (event.type()==QEvent.KeyPress) and (event.key()==Qt.Key_Tab):
        if (event.type()==QEvent.KeyPress) and (event.key()==Qt.Key_Space):
            self.signalTabPressed.emit("Key Space; ")
            return True
        if (event.type()==QEvent.KeyPress) and (event.key()==Qt.Key_W):
            self.signalTabPressed.emit("Key W; ")    
            return True

        return QLineEdit.event(self, event)



def main(): 
    app = QApplication(sys.argv) 
    w   = MyWindow() 
    w.show() 
    sys.exit(app.exec_()) 

if __name__ == "__main__": 
    main()

enter image description here

S. Nick
  • 12,879
  • 8
  • 25
  • 33
  • Yes, now it works with PyQt5, too. Thanks a lot. I will see if I can transfer this to the `QPushButton()` now. – Pandora Jun 17 '18 at 19:16
  • I'm not sure if your new code does what I intended, maybe we had some misunderstanding here. However, I got to a solution myself and that's mostly because of you. So thank you very much. :-) I will post my solution here too, for others who might come. – Pandora Jun 19 '18 at 19:07
0

With S. Nick's very useful answer I were able to come to a solution that really fits my needs.

class MyPushButton(QPushButton):
    def __init__(self, *args):
        QPushButton.__init__(self, *args)

    def event(self, event):
        if (event.type() == QEvent.KeyPress) and (event.key() == Qt.Key_Space):
            print(foo)

            return True

        return QPushButton.event(self, event)

So, that's it. Whenever I press the space key on my keyboard now it just prints foo and nothing else. Where print(foo) is just a place-holder for whatever I wish to do, obviously.

Pandora
  • 29
  • 1
  • 4