在QStyledItemDelegate中显示QComboBox文本而非索引值
我有一个模型,其中有一列是国家名。不过因为我想在表单中显示一个下拉框,让用户从选项中选择国家,所以我并没有直接把国家名存储在模型里。相反,我把一个索引值存储在一个允许的国家列表中。这样我就可以在我的表单视图中使用QComboBox
,这也是Qt文档推荐的做法。问题是我还有一个表格视图,而这个表格视图显示的是索引整数,而不是国家名。我设置了一个QStyledItemDelegate
,并实现了createEditor
,所以当你点击单元格时,它会弹出ComboBox
,但当你不在编辑国家时,你看到的还是索引值。
我已经部分解决了这个问题。我实现了一个绘制方法来处理这个问题,但它显示的值偏离了正确的位置,我还没搞清楚怎么才能让它正确显示。我觉得在渲染方法中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 个回答
4
模型有不同的数据角色来处理不同类型的数据。比如有一个叫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
,这个角色基本上就是为了这个目的而设计的。如果你在显示角色中使用原生类型,那么通常不需要进行任何自定义绘制,当然如果你愿意的话,也可以进行自定义。