Search code examples
pythonqtpyqtpyside6

Pyside6 respond to keyboard input


I'm using Pyside6

I want to change what widgets show in reaction to keyboard inputs from the user.

The minimum helpful example would be just a label that shows 1-5 depending on which number key the user presses.

My attempt (nothing gets printed, so I guess this is never called and I have to attach it to something):

    def keyPressEvent(self, event):
        key = event.key()
        print(f"Found key {key}")
        if key == QtCore.Qt.Key_1:
            self.selected_bin = 1
            self.set_current_bin()
        elif key == QtCore.Qt.Key_2:
            self.selected_bin = 2
            self.set_current_bin()
        elif key == QtCore.Qt.Key_3:
            self.selected_bin = 3
            self.set_current_bin()
        elif key == QtCore.Qt.Key_4:
            self.selected_bin = 4
            self.set_current_bin()
        elif key == QtCore.Qt.Key_5:
            self.selected_bin = 5
            self.set_current_bin()
        else:
            super(self).keyPressEvent(event)

    def set_current_bin(self):
        self.ui.current_bin.setText(f"Current bin: {self.selected_bin}")

I feel like this is super simple, but I've searched for about half an hour with no luck.


Solution

  • Install an event filter that listens for key presses and then set the label text to the event's key text value.

    Here is a working example:

    from PySide6.QtWidgets import *
    from PySide6.QtCore import *
    from PySide6.QtGui import *
    
    class Window(QWidget):
    
        def __init__(self, parent=None):
            super().__init__(parent=parent)
            self.layout = QHBoxLayout(self)
            self.label1 = QLabel("", self)
            self.label2 = QLabel("Key Pressed: ", self)
            self.layout.addWidget(self.label2)
            self.layout.addWidget(self.label1)
            self.resize(100,50)
            self.eventFilter = KeyPressFilter(parent=self)
            self.installEventFilter(self.eventFilter)
    
    class KeyPressFilter(QObject):
    
        def eventFilter(self, widget, event):
            if event.type() == QEvent.KeyPress:
                text = event.text()
                if event.modifiers():
                    text = event.keyCombination().key().name.decode(encoding="utf-8")
                widget.label1.setText(text)
            return False
    
    
    
    if __name__ == '__main__':
        app = QApplication([])
        window = Window()
        window.show()
        app.exec()