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_())