当多个视图共享单个模型时 [英] When single model is shared by multiple views
问题描述
有两个视图:
listView=QtGui.QListView()
tableView==QtGui.QTableView()
我继续定义一个自定义 DataModel
以供 listView
和 tableView
使用:
I go ahead and define a custom DataModel
to be used by both listView
and tableView
:
class DataModel(QtCore.QAbstractTableModel):
def __init__(self):
QtCore.QAbstractTableModel.__init__(self)
self.data=[['One':'Two'],['Three','Four']]
def data(self, index, role):
row=index.row()
if requested by listView:
return self.data[row][0]
elif requested by tableView:
return self.data[row][1]
最后将模型的实例分配给两个视图:
Finally assigning the instance of the model to both views:
model=DataModel()
listView.setModel(model)
tableView.setModel(model)
由于两个视图共享相同的模型,因此模型可能需要根据请求的视图小部件返回不同的值.如果您查看 data()
方法,则有假的 if/elif 语句显示了我需要的内容.有什么方法可以从模型方法内部执行此逻辑:if Requested by ListView...
和 elif requests by TableView
Since both views share the same model there is a chance the model would need to return different values based on what view widget is requesting it. If you take a look at data()
method there is fake if/elif statement showing what I need. Is there any way to do this logic from inside of model methods: if requested by ListView...
and elif requested by TableView
import os,sys
from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)
elements={'Animals':{0:'Bison',1:'Panther',2:'Elephant'},'Birds':{0:'Duck',1:'Hawk',2:'Pigeon'},'Fish':{0:'Shark',1:'Salmon',2:'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()
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 and not self.columnCount():
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==0:
return QtCore.QVariant("Spicie 0")
elif column==1:
return QtCore.QVariant("Spicie 1")
elif column==2:
return QtCore.QVariant("Spicie 2")
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)
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'%key
window=Window()
sys.exit(app.exec_())
推荐答案
完成,隐藏第零个键"列:
Done, by hiding the zeroth "key" column:
class DataModel(QtCore.QAbstractTableModel):
def __init__(self):
QtCore.QAbstractTableModel.__init__(self)
self.modelDict={}
self.names=[]
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.names)
def columnCount(self, index=QtCore.QModelIndex()):
return 4
def data(self, index, role):
if not index.isValid() or not (0<=index.row()<len(self.names)): return QtCore.QVariant()
row,col = index.row(),index.column()
if col==0:
if role==QtCore.Qt.DisplayRole:
return self.names[row]
else:
if role==QtCore.Qt.DisplayRole:
return self.modelDict[self.names[row]][col]
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.names.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)
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)
self.proxyModel.setFilterRegExp('%s'%key)
这篇关于当多个视图共享单个模型时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!