【问题标题】:Drill down QListWidget向下钻取 QListWidget
【发布时间】:2020-12-24 16:02:32
【问题描述】:

我可以在 QListWidget 中显示项目列表,然后单击获取所选项目。我似乎无法弄清楚如何深入研究数据(我不想使用树视图)。

例如,第一个列表可以是电视节目列表。单击节目会显示季节列表。点击一季会显示剧集列表。

我可以清除并将项目添加回树,但我想保留返回上一个列表的能力。

是否会隐藏顶层列表、创建新列表并添加一个后退项目元素,单击该元素会删除顶层并显示上一个列表?

【问题讨论】:

    标签: pyqt5 qlistwidget


    【解决方案1】:

    您可以使用具有树状结构的模型和 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"],
        },
    }
    
    # https://stackoverflow.com/a/53747062
    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_())
    

    【讨论】:

    • 谢谢,这确实给了我想要的结果(虽然我不理解一半的代码,对 PyQt5 来说还是新手)。我可以做这个延迟加载吗?例如点击 item3 调用一个返回 items3-1, items3-2....
    • @MavWolverine 我可以做这个延迟加载吗?是的,你可以这样做,检查 QAbstractItemModel 类的 canFetchMore 和 fetchMore 方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多