在 QStyledItemDelegate 中显示 QComboBox 文本而不是索引值
Posted
技术标签:
【中文标题】在 QStyledItemDelegate 中显示 QComboBox 文本而不是索引值【英文标题】:Displaying QComboBox text rather than index value in QStyledItemDelegate 【发布时间】:2010-08-25 17:00:02 【问题描述】:所以我有一个模型,其中一列包含一个国家/地区。但是,因为我想显示一个组合框来从选项列表中选择国家,所以我不直接将国家名称存储在模型中。相反,我将索引值存储到允许的国家列表中。这允许我按照 Qt 文档中的建议在我的表单视图中使用QComboBox
。问题是我也有一个表格视图,表格视图显示索引整数,而不是国家名称。我已经设置了QStyledItemDelegate
并实现了createEditor
,所以如果你点击世界单元格,它会弹出ComboBox
,但是当你不编辑国家时,你会看到索引值。
我正在寻求解决方案。我已经实现了一种绘制方法来完成这项工作,但它显示的是偏移到它的正确位置的值,我不知道如何让它正确显示。我认为render方法中的option.rect.topLeft()
是错误的,但是我无法弄清楚如何正确设置绘图。
def paint(self, painter, option, index):
if index.column() == COUNTRY:
painter.save()
countryRef, ok = inex.data().toInt()
countryStr = country_list[countryRef]
widget = QLineEdit()
widget.setGeometry(option.rect)
widget.setText(countryStr)
widget.render(painter, option.rect.topLeft())
painter.store()
else:
QStylyedItemDelegate.paint(self, painter, option, index)
【问题讨论】:
【参考方案1】:模型对于不同的数据有不同的item data roles。有Qt::DisplayRole
、Qt::EditRole
和Qt::UserRole
等等。在这种情况下,您希望显示与实际数据不同的内容,因此添加一个新角色,例如用于您的索引的 Qt::UserRole+1
。
那么您希望您的委托在setModelData 中设置适当的数据:
def setModelData(self, editor, model, index):
cbIndex = editor.currentIndex()
model.setData(index, cbIndex, Qt.UserRole+1)
# we want a nice displayable though
model.setData(index, countryIndexToDisplayable(cbIndex), Qt.DisplayRole)
当然,您将以类似的方式检索要在编辑器中设置的数据:
def setEditorData(self, widget, index):
widget.setCurrentIndex(index.data(Qt.UserRole+1))
根据您的模型和视图,您可能可以使用Qt::EditRole
,这几乎就是为此目的而设计的。如果您随后使用本机类型作为显示角色,则不需要进行任何自定义绘画,但如果您愿意,也可以这样做。
【讨论】:
+1 非常出色,谢谢。我不知道您可以创建用户定义的角色。我的感觉是,如果您使用一个角色更新数据,模型应该处理更新该数据的所有其他角色,但这在示例中会更难显示。 次要问题,在委托的 setModelData 方法中,我必须将 cbIndex 转换为 QVariant,如下所示:model.setData(index, QVariant(cbIndex), Qt.UserRole+1)。这是因为我有一个使用 QDataWidgetMapper 访问数据的表单,它总是将 QVariants 发送到模型,我需要保持一致。模型可能应该总是返回数据并具有 Qt 原生数据类型的数据集,而不是 Python 类型? @Simon - 我的偏好是拥有一个丰富的模型,一个代表您正在使用的领域的词汇表的模型。所以我希望有一个名为setCountry
的方法,它带有一个用于将索引转换为国家/地区的助手。我喜欢制作一个丰富的模型,它不是QAbstractItemModel
,而是我可以轻松地在 GUI 模型中委托给它的模型。如果我不这样做,我只需在 QAbstractItemModel
上创建提供更丰富 API 的访问器。 RE: QVariant(cbIndex),我已经有一段时间没有做任何 PyQt 并且我认为它会自动转换,就像在 C++ 中一样。
我明白你的意思,如果你用自己的访问器扩展模型,那么让它们尽可能方便是有意义的。不确定自动转换,PyQt 通常在这方面很棒,所以不知道那里发生了什么。也许是我的错。以上是关于在 QStyledItemDelegate 中显示 QComboBox 文本而不是索引值的主要内容,如果未能解决你的问题,请参考以下文章
QStyledItemDelegate 绘制自定义小部件失败
QStyledItemDelegate - updateEditorGeometry 如何工作?
QStyledItemDelegate中如何根据qStylesheet进行绘制
在带有 QSqlQueryModel 的 QListView 上使用 QStyledItemDelegate