python - 如何在使用 .model 时将拇指或图标分配给 QListView 项目

标签 python qt pyqt

下面的代码创建一个包含三个项目的 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”时,没有可用的项目(而是索引)。请指教。

enter image description here

    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 等)

enter image description here

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()

尽管我个人建议使用一个字典,其值同时包含 DisplayRoleDecorationRole 数据作为类上的字段。

我不知道默认情况下QListView是否会从模型请求DecorationRole。您可能需要设置 iconSize ListView 上的属性,或类似的。不过,这些都是您需要对模型本身进行的更改。

关于python - 如何在使用 .model 时将拇指或图标分配给 QListView 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25879376/

相关文章:

python - 检测几乎重复的行

c++ - 将 QString 转换为 QJsonArray

c++ - 以 C++ 对象的形式访问 QML 插件代码

python - 在 QWidget (pyqt5) 上的 QPixmap 上绘制点

Python 代码中的 Ubuntu : How to use PDB when you have sys. 标准输入中的 Python 调试器?

python - 无法在 QFileDialog 中为文件添加扩展名

python - 如何在没有数据或彩色图像的情况下获得清晰的图像。 opencv python

c++ - 如何在qt中的QTableWidget中获取comboBox项后的行号

python - 如何将类方法的输出获取到全局变量中

python - 如何更新pyqt中的图表之类的东西