[英]How QSortFilterProxyModel works
The code below creates a window with QListView
(left) and QTableView
(right). 下面的代码使用
QListView
(左)和QTableView
(右)创建一个窗口。 Both Views share the same data model. 两个视图共享相同的数据模型。
QListView
lists the dictionary keys such as 'Animals','Fish' and 'Birds'. QListView
列出字典键,例如“动物”,“鱼”和“鸟”。 When a left-side view's 'Animals' item is clicked a right-side view should display: a first column: 'Bison', a second column: 'Panther' and third: 'Elephant'. 单击左侧视图的“动物”项时,应显示右侧视图:第一列:“野牛”,第二列:“豹”,第三列:“大象”。
To address this goal there was QSortFilterProxyModel
assigned to right-side QTableView
to filter its context. 为了实现此目标,将
QSortFilterProxyModel
分配给右侧QTableView
来过滤其上下文。 Every mouse click performed on a left-side QListView triggers onClick()
function. 在左侧QListView上执行的每次鼠标单击都会触发
onClick()
函数。 This function checks what the left-side view's current item is. 此功能检查左侧视图的当前项目。 Then it queries the name of the key and a key's corresponding value from
self.modelDict
dictionary. 然后,它从
self.modelDict
字典中查询键的名称和键的对应值。
Here is a window screenshot: 这是一个窗口截图:
Apparently the code doesn't do what it is supposed to. 显然,代码没有执行应有的功能。
QSortFilterProxyModel
does indeed display a correct "item"... so both views are in sync. QSortFilterProxyModel
确实显示了正确的“项目” ...因此两个视图是同步的。 That's good. 那很好。 But the right-side-table view is displaying the same key name in every column: "Animals","Animals","Animals".
但是右侧表视图在每列中显示相同的键名称:“动物”,“动物”,“动物”。 While the goal once again is to display the list of the animals themselves taken from a dictionary received from
.data()
method: 目标是再次显示从
.data()
方法接收的词典中提取的动物本身的列表:
value=self.dataModel.data(index, QtCore.Qt.ItemDataRole)
where value is a dictionary such as: 其中value是一个字典,例如:
{1:'Bison',2:'Panther',3:'Elephant'}
Please advise. 请指教。
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
should return different data for different rows. DisplayRole
应该为不同的行返回不同的数据。
Accodring to your code: 根据您的代码:
If data
is called with index(1,0)
it returns Animals
. 如果使用
index(1,0)
调用data
,则返回Animals
。
If data
is called with index(1,1)
it returns Animals
. 如果使用
index(1,1)
调用data
,则返回Animals
。
If data
is called with index(1,2)
it returns Animals
. 如果使用
index(1,2)
调用data
,则返回Animals
。
Instead it should be 相反,它应该是
If data
is called with index(1,0)
it returns Animals
. 如果使用
index(1,0)
调用data
,则返回Animals
。
If data
is called with index(1,1)
it returns Bison
. 如果使用
index(1,1)
调用data
,则返回Bison
。
If data
is called with index(1,2)
it returns Panther
. 如果使用
index(1,2)
调用data
,则返回Panther
。
If data
is called with index(1,3)
it returns Elephant
. 如果使用
index(1,3)
调用data
,则返回Elephant
。
Totally 4 columns. 共4列。
To hide the first column which is a group name from the table view use hideColumn(0)
. 要从表视图中隐藏作为组名的第一列,请使用
hideColumn(0)
。
ps. PS。
ItemDataRole
is a enum name not a value. ItemDataRole
是枚举名称,而不是值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.