下面的代码创建了一个QListView
,其中包含数据和代理模型"附加"。
单击其中一个单选按钮可调用buttonClicked()
功能。
此函数调用模型的.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')
?
这些数据是否可访问,或者是"保留"并且无法查询?
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_())
答案 0 :(得分:5)
以下是有关如何使用QTableView
填充QStandardItemModel
填充QStandardItem
的工作示例。
使用QtGui.QStandardItemModel
优于QtCore.QAbstractListModel
的一个明显优势是,QtGui.QStandardItemModel
不必进行细分,以便分配到QTableView
。
你只需继续宣布:
view=QtGui.QTableView() # declare table view
model=QtGui.QStandardItemModel() # declare model
view.setModel(model) # assign model to table view
创建一个视图项首先声明它:
item=QtGui.QStandardItem('My Item Name') # stored 'My Item Name' can be queried using `Qt.DisplayRole` flag
使用以下方式分配声明的QStandardItem
进行查看:
model.appendRow(item)
model.appendRow(item)
方法“创建”与表视图中的列一样多QModelIndex
es。因此,无需为一行中的每一列手动创建QModelIndex
es:项目分配给的行。
接下来,使用item.setData(value,role)
方法,您可以使用预定义的QModelIndex
角色之一存储任何类型的数据,例如:
item.setData('< Column 0 My Display Value as "DisplayRole" >', QtCore.Qt.DisplayRole)
item.setData('< Column 0 My Custom Value as "UserRole" >', QtCore.Qt.UserRole)
item.setData('< Column 0 My Custom Value as "UserRole+1" >', QtCore.Qt.UserRole+1)
上面的所有三个赋值行都用于为同一个“item”分配三个不同的值:第一个值是一个字符串'< Column 0 My Display Value as "DisplayRole" >'
,它存储在Qt.DisplayRole
个角色下(使用此角色来检索它)背部)。
字符串值:'< Column 0 My Custom Value as "UserRole" >'
存储在Qt.UserRole
下。使用此角色将其检索回来。等等。
虽然item.setData(value,role)
方法非常有用并且确实使用了简单的语法,但它也非常有限,因为它只处理存储在项目所分配的行的零列中的单个QModelIndex
。为了能够存储存储在项目行的非零列中的自定义数据(或修改现有数据),我们首先得到项目的行号:
itemRow=item.row()
知道项目的行号,我们可以使用每列来获取所有项目索引 在“手动”模式下:
indexOfColumn1=model.index(itemRow, 1)
indexOfColumn2=model.index(itemRow, 2)
(其中第二个整数参数,例如1
或2
是列号)。
或处于“全自动”模式:
for i in range(model.columnCount()):
eachColumnIndex=model.index(itemRow, i)
知道项目QModelIndexes
我们可以使用它们查询或存储数据,就像我们使用item.setData()
方法一样(一种只从/向零列分配/检索数据的方法{{ 1}})。
为了存储和检索每列中的数据 - QModelIndex
,我们必须使用QModelIndex
和model.setData(index,value,role)
方法(看来我们无法使用model.data(index, role)
实例直接......就像这样:
QModelIndex
- 这是无效的代码,因为myIndex.setData(value,role)
没有QModelIndex
方法。
为了检索按.setData()
存储的数据,我们使用QModelIndex
:
model.data(index,role)
对于单个列视图(例如model=view.model()
print model.data(index, QtCore.Qt.UserRole+1).toPyObject()
),处理提供的.QListView
方法可能就足够了。但对于多列视图(例如QStandardItem
,有可能必须访问单个列的QTabLeView
。
QModelIndexe