Простейшим решением является получение событий клавиатуры либо путем создания подкласса редактирования строки и переопределения keyPressEvent
, либо с помощью фильтра событий и установки фокуса, если ключевым событием является Qt.Key_Down
.
Создание подкласса
В этом случае мы используем подкласс и настраиваемый сигнал, всякий раз, когда нажимается клавиша «вниз», он излучает сигнал, который связан с setFocus()
в основном классе.
class DownKeyEdit(QtWidgets.QLineEdit):
downKeyPressed = QtCore.pyqtSignal()
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Down:
self.downKeyPressed.emit()
event.accept()
else:
super().keyPressEvent(event)
class Test(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.lineEdit = DownKeyEdit()
layout.addWidget(self.lineEdit)
self.listWidget = QtWidgets.QListWidget()
layout.addWidget(self.listWidget)
self.listWidget.addItems(['Item {}'.format(i + 1) for i in range(10)])
self.lineEdit.downKeyPressed.connect(self.listWidget.setFocus)
Фильтрация событий
Использование фильтра событий позволяет нам избежать ненужного подкласса, поскольку он нам нужен только для этого конкретного случая c. Мы фильтруем ключевые события и проверяем правильность ключа, а затем соответственно устанавливаем фокус.
class Test(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.lineEdit = QtWidgets.QLineEdit()
layout.addWidget(self.lineEdit)
self.listWidget = QtWidgets.QListWidget()
layout.addWidget(self.listWidget)
self.listWidget.addItems(['Item {}'.format(i + 1) for i in range(10)])
self.lineEdit.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.KeyPress and event.key() == QtCore.Qt.Key_Down:
self.listWidget.setFocus()
event.accept()
return super().eventFilter(source, event)
Обратите внимание, что в обоих случаях я не рассматривал возможность QCompleter, который использует клавиши со стрелками для выбора возможные доработки.