向下钻取 QListWidget
Drill down QListWidget
我可以在 QListWidget 中显示项目列表,并在单击时选择项目。我似乎无法弄清楚如何向下钻取数据(我不想使用树视图)。
例如,第一个列表可以是电视节目列表。单击节目会显示季节列表。单击一个季节会显示剧集列表。
我可以清除项目并将其添加回树中,但我想保留返回到上一个列表的能力。
是否会隐藏顶部列表,创建新列表,并添加一个返回项元素,单击它会删除顶部并显示上一个列表?
您可以使用具有树状结构的模型和 QListView 并更改视图的 rootIndex,而不是重新创建 QListWidget 的信息:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
data = {
"item1": {
"item 1-1": ["item 1-1-1", "item 1-1-2", "item 1-1-3"],
"item 1-2": ["item 1-2-1", "item 1-2-2", "item 1-2-3"],
"item 1-3": ["item 1-3-1", "item 1-3-2", "item 1-3-3"],
},
"item2": {
"item 2-1": ["item 2-1-1", "item 2-1-2", "item 2-1-3"],
"item 2-2": ["item 2-2-1", "item 2-2-2", "item 2-2-3"],
"item 2-3": ["item 2-3-1", "item 2-3-2", "item 2-3-3"],
},
"item3": {
"item 3-1": ["item 3-1-1", "item 3-1-2", "item 3-1-3"],
"item 3-2": ["item 3-2-1", "item 3-2-2", "item 3-2-3"],
"item 3-3": ["item 3-3-1", "item 3-3-2", "item 3-3-3"],
},
}
#
def fill_model_from_json(parent, d):
if isinstance(d, dict):
for k, v in d.items():
child = QtGui.QStandardItem(str(k))
parent.appendRow(child)
fill_model_from_json(child, v)
elif isinstance(d, list):
for v in d:
fill_model_from_json(parent, v)
else:
parent.appendRow(QtGui.QStandardItem(str(d)))
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.view = QtWidgets.QListView()
self.button = QtWidgets.QPushButton("Up")
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.view)
lay.addWidget(self.button)
self.button.setEnabled(False)
self.view.clicked.connect(self.handle_view_clicked)
self.button.clicked.connect(self.handle_button_clicked)
model = QtGui.QStandardItemModel()
self.view.setModel(model)
fill_model_from_json(model.invisibleRootItem(), data)
@QtCore.pyqtSlot(QtCore.QModelIndex)
def handle_view_clicked(self, index):
if self.view.model().hasChildren(index):
self.view.setRootIndex(index)
self.button.setEnabled(self.view.rootIndex().isValid())
@QtCore.pyqtSlot()
def handle_button_clicked(self):
self.view.setRootIndex(self.view.rootIndex().parent())
self.button.setEnabled(self.view.rootIndex().isValid())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
我可以在 QListWidget 中显示项目列表,并在单击时选择项目。我似乎无法弄清楚如何向下钻取数据(我不想使用树视图)。
例如,第一个列表可以是电视节目列表。单击节目会显示季节列表。单击一个季节会显示剧集列表。
我可以清除项目并将其添加回树中,但我想保留返回到上一个列表的能力。
是否会隐藏顶部列表,创建新列表,并添加一个返回项元素,单击它会删除顶部并显示上一个列表?
您可以使用具有树状结构的模型和 QListView 并更改视图的 rootIndex,而不是重新创建 QListWidget 的信息:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
data = {
"item1": {
"item 1-1": ["item 1-1-1", "item 1-1-2", "item 1-1-3"],
"item 1-2": ["item 1-2-1", "item 1-2-2", "item 1-2-3"],
"item 1-3": ["item 1-3-1", "item 1-3-2", "item 1-3-3"],
},
"item2": {
"item 2-1": ["item 2-1-1", "item 2-1-2", "item 2-1-3"],
"item 2-2": ["item 2-2-1", "item 2-2-2", "item 2-2-3"],
"item 2-3": ["item 2-3-1", "item 2-3-2", "item 2-3-3"],
},
"item3": {
"item 3-1": ["item 3-1-1", "item 3-1-2", "item 3-1-3"],
"item 3-2": ["item 3-2-1", "item 3-2-2", "item 3-2-3"],
"item 3-3": ["item 3-3-1", "item 3-3-2", "item 3-3-3"],
},
}
#
def fill_model_from_json(parent, d):
if isinstance(d, dict):
for k, v in d.items():
child = QtGui.QStandardItem(str(k))
parent.appendRow(child)
fill_model_from_json(child, v)
elif isinstance(d, list):
for v in d:
fill_model_from_json(parent, v)
else:
parent.appendRow(QtGui.QStandardItem(str(d)))
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.view = QtWidgets.QListView()
self.button = QtWidgets.QPushButton("Up")
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.view)
lay.addWidget(self.button)
self.button.setEnabled(False)
self.view.clicked.connect(self.handle_view_clicked)
self.button.clicked.connect(self.handle_button_clicked)
model = QtGui.QStandardItemModel()
self.view.setModel(model)
fill_model_from_json(model.invisibleRootItem(), data)
@QtCore.pyqtSlot(QtCore.QModelIndex)
def handle_view_clicked(self, index):
if self.view.model().hasChildren(index):
self.view.setRootIndex(index)
self.button.setEnabled(self.view.rootIndex().isValid())
@QtCore.pyqtSlot()
def handle_button_clicked(self):
self.view.setRootIndex(self.view.rootIndex().parent())
self.button.setEnabled(self.view.rootIndex().isValid())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())