簡體   English   中英

QSortFilterProxyModel如何工作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM