PyQT5 使用箭头键在列表框之间移动焦点

PyQT5 Moving focus between list boxes using arrow keys

我有一个 QT 小部件,它有两个列表框,它们包装在 QFrames 中以及一个标签,并排放置在 QWidget 上。我可以使用 Tab 键在它们之间移动,但我想使用左右箭头键在它们之间移动。执行此操作的最佳方法是什么?

我的 QWidget 和 ListWidget 如下所示

class MainWindow(QWidget):

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

        self.init_ui()

    def init_ui(self):
        hbox = QHBoxLayout()
        hbox.addWidget(Left())
        hbox.addWidget(Right())
        self.setLayout(hbox)
        self.show()


class Left(QFrame):

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

        self.initUI()


    def initUI(self):
        header = QLabel()
        header.setText('Left')

        l = QListWidget()
        items = ['Item %s' % (i + 1) for i in range(10)]
        l.addItems(items)

        vbox = QVBoxLayout()
        vbox.addWidget(header)
        vbox.addWidget(l)

        self.setLayout(vbox)



class Right(QFrame):

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

        self.initUI()

    def initUI(self):
        header = QLabel()
        header.setText('Right')

        l = QListWidget()
        items = ['Item %s' % (i + 1) for i in range(10)]
        l.addItems(items)

        vbox = QVBoxLayout()
        vbox.addWidget(header)
        vbox.addWidget(l)

        self.setLayout(vbox)


def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

您可以在列表小部件上安装事件过滤器,然后使用其父小部件的 focusNextPrevChild 方法移动焦点:

class MainWindow(QWidget):
    ...
    def init_ui(self):
        hbox = QHBoxLayout()
        self.left = Left()
        self.left.installEventFilter(self)
        hbox.addWidget(self.left)
        self.right = Right()
        self.right.installEventFilter(self)
        hbox.addWidget(self.right)
        self.setLayout(hbox)
        self.show()

    def eventFilter(self, source, event):
        if (event.type() == QEvent.KeyPress and
            (event.key() == Qt.Key_Left or event.key() == Qt.Key_Right) and
            event.modifiers() == Qt.NoModifier and
            (source is self.left or source is self.right)):
            self.focusNextPrevChild(event.key() == Qt.Key_Right)
            return True
        return super(MainWindow, self).eventFilter(source, event)