在QStyledItemDelegate中显示QComboBox文本而不是索引值
问题描述:
所以我有一个模型,其中一列包含一个国家。但是因为我想显示一个组合框来从选项列表中选择国家,所以我不直接在模型中存储国家名称。相反,我将索引值存储在允许国家的列表中。这允许我在Qt文档中建议的表单视图中使用QComboBox
。问题是我也有一个表视图,表视图显示索引整数,而不是国家名称。我建立了一个QStyledItemDelegate
并实施createEditor
,所以如果你点击世界单元格,它会弹出ComboBox
,但是当你不编辑国家时,你会看到索引值。在QStyledItemDelegate中显示QComboBox文本而不是索引值
我是解决方案的一部分。我已经实现了一个绘制方法来完成这个工作,但是它显示的是偏移量正确的位置,我不知道如何让它正确显示。我认为在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)
答
不同的数据模型有不同的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杰出,谢谢。我不知道你可以创建用户定义的角色。我的感觉是,如果您使用一个角色更新数据,模型应该处理更新数据的所有其他角色,但在示例中难以显示。 – 2010-08-26 09:49:01
小问题,在委托的setModelData方法中,我必须将cbIndex转换为QVariant,如下所示:model.setData(index,QVariant(cbIndex),Qt.UserRole + 1)。这是因为我有一个使用QDataWidgetMapper访问数据的表单,并且它始终将QVariants发送到模型,我需要保持一致。模型应该总是返回数据并且在Qt本地数据类型中设置数据,而不是Python类型? – 2010-08-26 13:02:26
@Simon - 我的首选是拥有丰富的模型,代表您正在使用的域的词汇表。所以我希望有一个名为'setCountry'的方法,它有一个帮助器将索引转换为一个国家。我喜欢创建一个不是'QAbstractItemModel'的丰富模型,而是我可以轻松地在GUI模型中委托的模型。如果我不这样做,我只是在'QAbstractItemModel'上创建访问器来提供更丰富的API。 RE:QVariant(cbIndex),因为我已经完成了任何PyQt,并且我认为它会自动转换,就像在C++中一样。 – 2010-08-26 15:27:27