Python 链接的视图列表使用什么设计逻辑

Python 链接的视图列表使用什么设计逻辑,python,qt,pyqt,Python,Qt,Pyqt,有一本字典有三个键:“动物”、“鸟”和“鱼” 主对话框有两个列表视图。左视图viewA显示上述按键列表。 单击其中一个项目时,右视图viewB显示物种列表 问题是如何管理视图的显示。。。假设用户单击“动物”:listB继续并为列表中的每种动物构建一个全新的QListWidgetItem列表。然后用户单击“Birds”。我应该如何处理已生成的viewB的“动物”项目?我应该把它们藏起来吗?(隐藏“动物”项目(而不是删除)将允许我在以后再次单击“动物”时取消隐藏它们(如果列表项大量使用图形:拇指、图

有一本字典有三个键:“动物”、“鸟”和“鱼”

主对话框有两个列表视图。左视图
viewA
显示上述按键列表。 单击其中一个项目时,右视图
viewB
显示物种列表

问题是如何管理视图的显示。。。假设用户单击“动物”:
listB
继续并为列表中的每种动物构建一个全新的QListWidgetItem列表。然后用户单击“Birds”。我应该如何处理已生成的
viewB
的“动物”项目?我应该把它们藏起来吗?(隐藏“动物”项目(而不是删除)将允许我在以后再次单击“动物”时取消隐藏它们(如果列表项大量使用图形:拇指、图标等,则完全有意义。如果动物列表超过1000个,则从头开始重建列表项和取消隐藏上次单击生成的列表项之间会有明显的区别)。
我看到的另一种方法是每次单击
viewA
的项目时使用
viewB.clear()
。因此每次单击
listA
项目时都会重建
listB
项目。但正如我在一个长长的项目列表中提到的,它可能非常慢。在这种情况下,应该实现什么逻辑

from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        layout=QtGui.QHBoxLayout()
        self.setLayout(layout)        

        self.viewA=QtGui.QListWidget()
        self.viewA.addItems(elements.keys())
        self.viewA.itemClicked.connect(self.aClicked)
        self.viewB=QtGui.QListWidget()   

        layout.addWidget(self.viewA)
        layout.addWidget(self.viewB)
        self.show()

    def aClicked(self, item):
        key='%s'%item.text()
        values=elements.get(key)
        items=[QtGui.QListWidgetItem(val) for val in values]
        result=[self.viewB.addItem(item) for item in items]

elements={'Animals':['Bison','Panther','Elephant'],'Birds':['Duck','Hawk','Pigeon'],'Fish':['Shark','Salmon','Piranha']}
window=Window()
sys.exit(app.exec_())

我建议改用这种方法

您将拥有两个模型:KeysModel和ValuesModel,这两个模型继承自
QAbstractListModel
QStringListModel
。两个视图
QTableView
:KeysView和ValuesView。还有一个代理模型
QSortFilterProxyModel
ProxyModel,它将帮助您在ValuesView中显示由键过滤的值


选择KeyView中的项目时,只需为ProxyModel分配一个新过滤器,ValuesView中的值将被更改。

在另一个类上,它可以设计数据层次结构。请尝试阅读文档。

为两个视图使用一个模型:QListView和QTableView:

导入操作系统,系统 从PyQt4导入QtCore、QtGui app=QtGui.QApplication(sys.argv) 元素={'Animals':{1:'Bison',2:'Panther',3:'Elephant',Birds':{1:'Duck',2:'Hawk',3:'鸽子'},'Fish':{1:'Shark',2:'Salmon',3:'Piranha'} 类数据模型(QtCore.QAbstractTableModel): 定义初始化(自): QtCore.QAbstractTableModel.\uuuu init\uuuu(self) self.modelDict={} self.items=[] def行数(self,parent=QtCore.QModelIndex()): 返回len(自我项目) def columnCount(self,index=QtCore.QModelIndex()): 返回4 def数据(自身、索引、角色):
如果没有index.isValid()或没有(0),请使用我的示例代码来说明您的想法。如果不了解如何将其组合在一起,就很难理解这个概念。提前感谢!Sputnix,请阅读@Ezee在回答中链接的有关模型/视图编程的文档。更容易“理解这个概念”,在研究之后,而不是让别人为你做工作!我发布的示例只有22行。编辑它来说明这个概念需要多长时间?这个论坛不仅仅是关于指向文档。我发现在代码中实现了这个概念之后,学习编程概念要容易得多。@Zero六十九:我的问题中发布的示例代码是我特意编写的一个
示例
代码,它不是从“real”复制/粘贴的生产代码。没有人被要求为其他人做工作。但是为了说明这个概念。太好了!太棒了!谢谢!这非常有用!使用
QColumnView
作为关键字,我现在可以整天用谷歌搜索它了!
import os,sys
from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)
elements={'Animals':{1:'Bison',2:'Panther',3:'Elephant'},'Birds':{1:'Duck',2:'Hawk',3:'Pigeon'},'Fish':{1:'Shark',2:'Salmon',3:'Piranha'}}

class DataModel(QtCore.QAbstractTableModel):
    def __init__(self):
        QtCore.QAbstractTableModel.__init__(self)
        self.modelDict={}    
        self.items=[]    
    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.items)   

    def columnCount(self, index=QtCore.QModelIndex()):
        return 4

    def data(self, index, role):
        if not index.isValid() or not (0<=index.row()<len(self.items)): return QtCore.QVariant()
        key=str(self.items[index.row()])
        column=index.column()

        if role==QtCore.Qt.ItemDataRole: return self.modelDict.get(str(index.data().toString()))

        if role==QtCore.Qt.DisplayRole:
            if column==0:
                return key
            else:
                return self.modelDict.get(key).get(column)  

    def addItem(self, itemName=None, column=0):
        totalItems=self.rowCount()+1
        self.beginInsertRows(QtCore.QModelIndex(), totalItems, column)
        if not itemName:            itemName='Item %s'%self.rowCount()
        self.items.append(itemName)
        self.endInsertRows()

    def buildItems(self):
        for key in self.modelDict:
            index=QtCore.QModelIndex()
            self.addItem(key) 

class ProxyTableModel(QtGui.QSortFilterProxyModel):
    def __init__(self, parent=None):
        super(ProxyTableModel, self).__init__(parent)

    def headerData(self, column, orientation, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.TextAlignmentRole:
            if orientation == QtCore.Qt.Horizontal:
                return QtCore.QVariant(int(QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter))
            return QtCore.QVariant(int(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter))
        if role != QtCore.Qt.DisplayRole:
            return QtCore.QVariant()

        if orientation==QtCore.Qt.Horizontal:
            if column==1:
                return QtCore.QVariant("Species 1")
            elif column==2:
                return QtCore.QVariant("Species 2")
            elif column==3:
                return QtCore.QVariant("Species 3")

        return QtCore.QVariant(int(column + 1))

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        mainLayout=QtGui.QHBoxLayout()
        self.setLayout(mainLayout)   

        self.dataModel=DataModel()
        self.dataModel.modelDict=elements
        self.dataModel.buildItems() 

        self.proxyModel=ProxyTableModel()
        self.proxyModel.setFilterKeyColumn(0)    
        self.proxyModel.setSourceModel(self.dataModel)

        self.viewA=QtGui.QListView()
        self.viewA.setModel(self.dataModel)
        self.viewA.clicked.connect(self.onClick) 

        self.viewB=QtGui.QTableView()         
        self.viewB.setModel(self.proxyModel)
        self.viewB.setColumnHidden(0,True)

        mainLayout.addWidget(self.viewA)
        mainLayout.addWidget(self.viewB)    
        self.show()

    def onClick(self):
        index=self.viewA.currentIndex()
        key=self.dataModel.data(index, QtCore.Qt.DisplayRole)  
        value=self.dataModel.data(index, QtCore.Qt.ItemDataRole)        
        self.proxyModel.setFilterRegExp('%s'%key)
        print 'onClick(): key: %s'%type('%s'%key)

window=Window()
sys.exit(app.exec_())