下面的代码创建了一个QListView
,数据和代理模型“附加”。 单击其中一个单选按钮可调用buttonClicked()
函数。如何访问存储在QModelIndex中的数据
该函数调用模型的.data(index,role)
方法来获取存储在当前索引中的数据。
对于DisplayRole
该模型的.data()
方法正确地返回索引的名称(在创建时分配给它)。但是,当使用
'ItemDataRole' 我正在一个错误:
TypeError: QSortFilterProxyModel.data(QModelIndex, int role=Qt.DisplayRole): argument 2 has unexpected type 'sip.enumtype'
-
Question 1: How to fix this error?
如果你看一看addItems()
方法有一行有:
self.setData(index, 'keyword')
显然我试图将'关键字'设置为我自己的“自定义数据”(它是什么ProxyModel将用于过滤索引?)。
问题2:如何查询我用self.setData(index, 'keyword')
设置的字符串“keyword”? 该数据是可访问的还是“保留”且无法查询?
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 ProxyModel(QtGui.QSortFilterProxyModel):
def __init__(self, parent=None):
super(ProxyModel, self).__init__(parent)
class DataModel(QtCore.QAbstractListModel):
def __init__(self):
QtCore.QAbstractListModel.__init__(self)
self.items=[]
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.items)
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()]
elif role==QtCore.Qt.ItemDataRole:
return index.data()
def addItems(self):
for key in elements:
index=QtCore.QModelIndex()
self.setData(index, 'keyword')
self.beginInsertRows(index, 0, 0)
self.items.append(key)
self.endInsertRows()
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
layout=QtGui.QVBoxLayout()
self.setLayout(layout)
self.view=QtGui.QListView()
self.dataModel=DataModel()
self.dataModel.addItems()
self.proxyModel=ProxyModel()
self.proxyModel.setSourceModel(self.dataModel)
self.view.setModel(self.proxyModel)
buttonsLayout=QtGui.QHBoxLayout()
animalsButton=QtGui.QRadioButton('Show Animals')
birdsButton=QtGui.QRadioButton('Show Birds')
fishButton=QtGui.QRadioButton('Show Fish')
self.buttons=[animalsButton,birdsButton,fishButton]
for button in self.buttons:
button.toggled.connect(self.buttonClicked)
buttonsLayout.addWidget(button)
layout.addWidget(self.view)
layout.insertLayout(1,buttonsLayout)
self.show()
def buttonClicked(self,arg=None):
for button in self.buttons:
if button.isChecked(): break
index=self.view.currentIndex()
print 'Index DisplayRole: %s'%self.view.model().data(index, QtCore.Qt.DisplayRole).toString()
# print 'ItemDataRole', self.view.model().data(index, QtCore.Qt.ItemDataRole)
window=Window()
sys.exit(app.exec_())
的“限制”请您谈谈并不真正存在。该你的例子的局限性在那里,因为你只在行中添加一个项目,你应该为每一列创建一个'QStandardItem',将它们放入一个列表中,并添加列表,例如'model.appendRow([item_for_col_1,item_for_col_2 ,item_for_col_3])'然后你可以在每个项目上调用'item_for_col_x.setData',如果你以后需要访问这些项目,你可以自己存储对它们的引用,或者使用像'i ndexToItem()'或'itemToIndex()'(如果需要,可能构造你自己的QModelIndex)。 – 2014-09-27 02:47:09
我要补充的最后一件事是,尽管'QModelIndex'变得无效(例如当或从模型中添加/删除),但项目不会。因此,只要您不想在第一次后续调用以任何方式修改模型后继续使用索引,就可以使用该项目随时查找索引。 – 2014-09-27 02:48:45