下面的代码创建一个包含三个项目的 QListView。该 QListView 通过其 .model 进行填充。如果不使用模型,我可以继续做这样的事情:
view=QtGui.QListWidget()
item=QtGui.QListWidgetItem()
item.setText('Item Name')
icon=QtGui.QIcon('/Volumes/path/to/file.jpg')
item.setIcon(icon)
view.addItem(item)
但是使用“.model”时,没有可用的项目(而是索引)。请指教。
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 Model(QtCore.QAbstractListModel):
def __init__(self):
QtCore.QAbstractListModel.__init__(self)
self.items=[]
self.modelDict={}
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()]
def addItems(self):
for key in self.modelDict:
index=QtCore.QModelIndex()
self.beginInsertRows(index, 0, 0)
self.items.append(key)
self.endInsertRows()
class ListView(QtGui.QListView):
def __init__(self):
super(ListView, self).__init__()
self.model= Model()
self.model.modelDict=elements
self.model.addItems()
self.setModel(self.model)
self.show()
window=ListView()
sys.exit(app.exec_())
编辑:感谢 Jeffrey 的详细解释!
下面的代码是之前发布的代码的修订后的完整工作版本。基本上我们必须向模型提供所需的数据。实际的图标“分配”将由模型本身处理。我们只需要确保图标请求发生在正确的 if Role==x
范围内。应在 .data()
方法的 if DecorationRole
部分请求/返回图标。还有其他可用的角色:Qt.DisplayRole、Qt.TextAlignmentRole、Qt.TextColorRole、Qt.BackgroundColorRole、Qt.ItemDataRole、Qt.UserRole
等)
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'}}
icon=QtGui.QIcon('C:\\myIcon.png')
class Model(QtCore.QAbstractListModel):
def __init__(self):
QtCore.QAbstractListModel.__init__(self)
self.items=[]
self.modelDict={}
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.DecorationRole:
return icon
def addItems(self):
for key in self.modelDict:
index=QtCore.QModelIndex()
self.beginInsertRows(index, 0, 0)
self.items.append(key)
self.endInsertRows()
class ListView(QtGui.QListView):
def __init__(self):
super(ListView, self).__init__()
self.model= Model()
self.model.modelDict=elements
self.model.addItems()
self.setModel(self.model)
self.show()
window=ListView()
sys.exit(app.exec_())
最佳答案
首先,您需要 Model.data
才能返回 QIcon
(或 QPixmap
,如果这样更方便的话)当传入的角色为DecorationRole
时。使用当前代码,它将返回 None
,这不仅不能满足您的要求,而且实际上是无效的。如果它不知道如何处理传递的角色,它应该返回一个无效的QVariant
(就像您在方法的第一行所做的那样)。不过,PyQt 可能足够聪明,可以正确处理 None
。
其次,您似乎已经正确使用了QModelIndex
。您可以将图标作为附加到模型本身的另一个字段,您可以类似地访问。 QListWidgetItem
只是一个便利类,没有什么可以阻止您将与存储在模型上的类似类中的行关联的所有数据封装起来(就像您已经对 所做的那样) >DisplayRole
数据)并通过 QModelIndex.row()
访问。
类似这样的事情:
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.DecorationRole:
return self.icons[index.row()]
return QtCore.QVariant()
尽管我个人建议使用一个字典,其值同时包含 DisplayRole
和 DecorationRole
数据作为类上的字段。
我不知道默认情况下QListView
是否会从模型请求DecorationRole
。您可能需要设置 iconSize
ListView 上的属性,或类似的。不过,这些都是您需要对模型本身进行的更改。
关于python - 如何在使用 .model 时将拇指或图标分配给 QListView 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25879376/