如何使用QStyledItemDelegate在列中渲染QIcons?

1 投票
1 回答
845 浏览
提问于 2025-04-17 05:15

我正在使用 QTableView 和 QSqlTableModel 来显示来自 sqlite 数据库的数据。在数据库(和模型)中,有一列字段包含路径,比如:'/home/foo/bar.txt',或者是空的。对于这一列,我希望在视图中为有路径的项目显示一个图标,而为没有路径的项目显示另一个图标(而且完全不显示实际的数据或路径)。
觉得我需要设置一个 QStyledItemDelegate 来用图标替代数据,但示例中的 staritemdelegate 强调了委托的编辑功能(我并不想要这个),而没有说明如何渲染 QIcons(或者我可能只是没找到)。我查阅了 API,但不太清楚如何子类化 QStyledItemDelegate,或者说在这种情况下是否真的需要这样做。
如果能给我一些关于这是否可行的指导,或者一个如何使用 QStyledItemDelegate 来为某一列渲染图标的示例(最好是用 python),我会非常感激。

编辑:Petr 的帖子解决了这个问题。基于 Petr 的解决方案,我描述的情况的完整实现是:

def data(self, index, role=QtCore.Qt.DisplayRole):  
    if index.column() == 2:  
        if role == QtCore.Qt.DecorationRole:  
            filename = super(MovieModel, self).data(index, QtCore.Qt.DisplayRole)  
            if not filename == '':  
                return self.yes_icon  
            else:  
                return self.no_icon    
        elif role == QtCore.Qt.DisplayRole:  
            return ''  
    #Other columns/roles:  
    return super(MovieModel, self).data(index, role)  

希望这能帮到你。

1 个回答

1

与其去继承代理类,不如继承模型类,然后在这个模型的 DecorationRole 中返回图标。

下面是一个未经过测试的解决方案草图:

class IconModel(QSqlTableModel):
    def data(self, index, role=Qt.DisplayRole):
        if index.column() == FILENAME_COLUMN_INDEX:
             if role == Qt.DecorationRole:
                  filename = super(IconModel, self).data(index, Qt.DisplayRole)
                  return icon_for_filename(filename)
             elif role == Qt.DisplayRole:
                  return ''
        # Other columns/roles:
        return super(IconModel, self).data(index, role)

继承代理类要麻烦得多。

撰写回答