当多个视图共享单个模型时

时间:2014-09-17 22:01:53

标签: python pyqt

有两种观点:

listView=QtGui.QListView()
tableView==QtGui.QTableView() 

我继续定义DataModellistView使用的自定义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]

最后将模型实例分配给两个视图:

model=DataModel()
listView.setModel(model)
tableView.setModel(model)

由于两个视图共享相同的模型,因此模型有可能需要根据请求它的视图窗口小部件返回不同的值。如果你看一下data()方法,就会有假的if / elif语句显示我需要的东西。有没有办法从模型方法内部执行此逻辑:if requested by ListView...elif requested by TableView

稍后编辑:

enter image description here

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

1 个答案:

答案 0 :(得分:2)

完成,隐藏第0条&#34;键&#34;柱:

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)