Search code examples
pythonpyqtpyqt5arrow-keys

Moving across elements using Up-Down keys


I make a program using PyQt5 and Python3.7. How to move across elements using arrow keys instead of tab key? (e.g. moving from button to textbox using down key)

import sys
from PyQt5.QtWidgets import QApplication, QLabel, QLineEdit, QMainWindow, QPushButton, QFileSystemModel, QTreeView, \
    QFileDialog, QComboBox
from PyQt5.QtCore import pyqtSlot


class App(QMainWindow):

    def __init__(self):
        super(App, self).__init__()

        self.title = 'by Qt5 and python 3.7'
        self.left = 10
        self.top = 10
        self.width = 1000
        self.height = 500

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.label = QLabel('File Name: ')
        self.label.move(20, 20)

        self.btn_browse = QPushButton('Browse', self)
        self.btn_browse.move(50, 20)
        self.btn_browse.clicked.connect(self.on_click)

        self.textbox = QLineEdit(self)
        self.textbox.move(170, 20)
        self.textbox.resize(280, 40)

        self.page_view = QLineEdit(self)
        self.page_view.move(20, 100)
        self.page_view.resize(800, 400)

        self.show()

    @pyqtSlot()
    def on_click(self):
        print('PyQt5 button click')
        # self.openFileNameDialog()
        # self.saveFileDialog()

if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())

Solution

  • One possible solution is to overwrite the keyPressEvent() method to detect the desired key and use focusNextPrevChild() by passing False or True if you want the focus to go to the previous or next widget, respectively.

    from PyQt5.QtCore import pyqtSlot, Qt
    
    
    class App(QMainWindow):
        # ...
        def keyPressEvent(self, e):
            if e.key() == Qt.Key_Down:
                self.focusNextPrevChild(True)
            elif e.key() == Qt.Key_Up:
                self.focusNextPrevChild(False)
    # ...