[英]How QSortFilterProxyModel works
下面的代码使用QListView
(左)和QTableView
(右)创建一个窗口。 两个视图共享相同的数据模型。
QListView
列出字典键,例如“动物”,“鱼”和“鸟”。 单击左侧视图的“动物”项时,应显示右侧视图:第一列:“野牛”,第二列:“豹”,第三列:“大象”。
为了实现此目标,将QSortFilterProxyModel
分配给右侧QTableView
来过滤其上下文。 在左侧QListView上执行的每次鼠标单击都会触发onClick()
函数。 此功能检查左侧视图的当前项目。 然后,它从self.modelDict
字典中查询键的名称和键的对应值。
这是一个窗口截图:
显然,代码没有执行应有的功能。 QSortFilterProxyModel
确实显示了正确的“项目” ...因此两个视图是同步的。 那很好。 但是右侧表视图在每列中显示相同的键名称:“动物”,“动物”,“动物”。 目标是再次显示从.data()
方法接收的词典中提取的动物本身的列表:
value=self.dataModel.data(index, QtCore.Qt.ItemDataRole)
其中value是一个字典,例如:
{1:'Bison',2:'Panther',3:'Elephant'}
请指教。
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 3
def data(self, index, role):
if not index.isValid() or not (0<=index.row()<len(self.items)): return QtCore.QVariant()
if role==QtCore.Qt.DisplayRole: return self.items[index.row()]
if role==QtCore.Qt.ItemDataRole: return self.modelDict.get(str(index.data().toString()))
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 ProxyModel(QtGui.QSortFilterProxyModel):
def __init__(self, parent=None):
super(ProxyModel, self).__init__(parent)
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=ProxyModel()
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)
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_())
DisplayRole
应该为不同的行返回不同的数据。
根据您的代码:
如果使用index(1,0)
调用data
,则返回Animals
。
如果使用index(1,1)
调用data
,则返回Animals
。
如果使用index(1,2)
调用data
,则返回Animals
。
相反,它应该是
如果使用index(1,0)
调用data
,则返回Animals
。
如果使用index(1,1)
调用data
,则返回Bison
。
如果使用index(1,2)
调用data
,则返回Panther
。
如果使用index(1,3)
调用data
,则返回Elephant
。
共4列。
要从表视图中隐藏作为组名的第一列,请使用hideColumn(0)
。
PS。 ItemDataRole
是枚举名称,而不是值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.