Код ниже создает окно с QListView
(слева) и QTableView
(справа). Оба представления используют одну и ту же модель данных.Как работает QSortFilterProxyModel
QListView
перечисляет ключи словаря, такие как «Животные», «Рыба» и «Птицы». Когда щелкнул элемент «Животные» в левом боку, справа должно отображаться: первый столбец: «Bison», второй столбец: «Panther» и третий: «Elephant».
Для решения этой задачи было определено, что QSortFilterProxyModel
присвоен праву QTableView
, чтобы отфильтровать его контекст. Каждый щелчок мыши выполняется с помощью левого QListView триггеров onClick()
. Эта функция проверяет текущий элемент текущего вида в левом. Затем он запрашивает имя ключа и соответствующее значение ключа от словаря self.modelDict
.
Вот скриншот окна:
Видимо код не делать то, что он должен. QSortFilterProxyModel
действительно отображает правильный «элемент» ... так что оба представления синхронизированы. Это хорошо. Но в правом столбце отображается одно и то же ключевое имя в каждом столбце: «Животные», «Животные», «Животные». Хотя цель еще раз, чтобы отобразить список самих животных, взятых из словаря, полученного от .data()
метода:
value=self.dataModel.data(index, QtCore.Qt.ItemDataRole)
где значение является словарем, такие как:
{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_())
QSortFilterModel предназначен для выбора подмножества одних и тех же элементов из модели - вы не должны удивляться тому, что у вас есть те же слова, что и в обоих представлениях. – mdurant
Находится довольно хорошо pyside-example: site: https: //qt.gitorious.org/pyside/pyside-examples/raw/060dca8e4b82f301dfb33a7182767eaf8ad3d024: examples/itemviews/basicsortfiltermodel.py – alphanumeric