有隐藏项目时关注下一个 QListWidget 项目
Posted
技术标签:
【中文标题】有隐藏项目时关注下一个 QListWidget 项目【英文标题】:Focusing on the next QListWidget item while there are hidden items 【发布时间】:2020-11-03 01:48:16 【问题描述】:在谈论我的问题之前,我想先谈谈我想做什么。
我希望带有我在QLineEdit
中写的单词的结果出现在QListWidget
中。
我想用键盘关注结果。
如果我用鼠标单击 Qlistwidget 并在那里聚焦,即使有隐藏项目,我也可以用键盘(上/下箭头键)聚焦下一个项目。系统自动完成,无需编写任何代码。
但我想在不失去对QLineEdit
的关注的情况下做到这一点。所以我决定使用QShortcut
:
self.__up_key = QShortcut(Qt.Key_Up, self)
self.__dw_key = QShortcut(Qt.Key_Down, self)
self.__up_key.activated.connect(self.__ctrl)
self.__dw_key.activated.connect(self.__ctrl)
def __ctrl(self):
curr = self._list_widget.currentRow()
if self.sender().key().toString() == "Up":
self._list_widget.setCurrentRow(curr - 1)
else:
self._list_widget.setCurrentRow(curr + 1)
如果没有隐藏项目,它的工作原理是这样的。但是如果有隐藏的项目,它们的索引仍然存在,所以即使下一个项目被隐藏,它也会选择它。我们当然看不到这一点。
我得出了这样一个结论:
def __ctrl(self):
if self.sender().key().toString() == "Up":
self._list_widget.setCurrentRow(self.prevVisibleItem())
else:
self._list_widget.setCurrentRow(self.nextVisibleItem())
def nextVisibleItem(self):
for row in range(self._list_widget.currentRow() + 1, self._list_widget.count()):
if not self._list_widget.isRowHidden(row):
return row
return self._list_widget.currentRow()
def prevVisibleItem(self):
for row in range(self._list_widget.currentRow() - 1, -1, -1):
if not self._list_widget.isRowHidden(row):
return row
return self._list_widget.currentRow()
我检查每个项目是否隐藏。这对我有用,但我正在寻找一种更有效的方法。当我专注于 QListWidget 时,我可以在每个项目之间导航,而无需编写任何代码。我想知道这是怎么发生的。
小例子:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QListWidget, QLineEdit, QShortcut
class Window(QWidget):
def __init__(self):
super().__init__()
self._layout = QVBoxLayout()
self.entry = QLineEdit()
self.entry.setPlaceholderText("Search")
self._list_widget = QListWidget()
__items = [str(i) + "- item" for i in range(6)]
self._list_widget.addItems(__items)
__hidden_items = [self._list_widget.item(1), self._list_widget.item(3), self._list_widget.item(5)]
for i in __hidden_items:
i.setHidden(True)
self.__up_key = QShortcut(Qt.Key_Up, self)
self.__dw_key = QShortcut(Qt.Key_Down, self)
self.__up_key.activated.connect(self.__ctrl)
self.__dw_key.activated.connect(self.__ctrl)
self._layout.addWidget(self.entry)
self._layout.addWidget(self._list_widget)
self.setLayout(self._layout)
self.show()
def __ctrl(self):
if self.sender().key().toString() == "Up":
self._list_widget.setCurrentRow(self.prevVisibleItem())
else:
self._list_widget.setCurrentRow(self.nextVisibleItem())
def nextVisibleItem(self):
for row in range(self._list_widget.currentRow() + 1, self._list_widget.count()):
if not self._list_widget.isRowHidden(row):
return row
return self._list_widget.currentRow()
def prevVisibleItem(self):
for row in range(self._list_widget.currentRow() - 1, -1, -1):
if not self._list_widget.isRowHidden(row):
return row
return self._list_widget.currentRow()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec_())
【问题讨论】:
【参考方案1】:更优雅的解决方案是使用 moveCursor 获取 QModelIndex 并将当前索引设置为视图:
def __ctrl(self):
shorcut = self.sender()
index = QModelIndex()
if shorcut.key() == QKeySequence(Qt.Key_Up):
index = self._list_widget.moveCursor(
QAbstractItemView.MoveUp, Qt.NoModifier
)
elif shorcut.key() == QKeySequence(Qt.Key_Down):
index = self._list_widget.moveCursor(
QAbstractItemView.MoveDown, Qt.NoModifier
)
if index.isValid():
self._list_widget.setCurrentIndex(index)
【讨论】:
以上是关于有隐藏项目时关注下一个 QListWidget 项目的主要内容,如果未能解决你的问题,请参考以下文章
Python:如何在 PyQt 中查询 QListWidget 中的多个选定项
在PyQt5中的QTreeWidget和QListWidget之间拖动项目?