QTableWidgetItem 构造函数的type 参数只是你 区分某些项目的一种方式,它不会使Qt 以任何不同的方式显示数据或进行类型转换或任何事情像那样。例如,您可以选择将type=1001 用于int 单元格,将type=1002 用于float 单元格,但您仍然需要自行从int/float <-> string 进行转换。
您可以使用data() 方法和自定义用户角色(或仅将QTableWidgetItem 子类化并将额外数据存储为属性)将几乎所有数据存储在QTableWidgetItem 上。但无论您在项目上存储什么额外数据,项目都需要向用户显示 something。您可以在display role 上设置字符串数据(这是setText() 所做的),或者使用QItemDelegate 在每个项目单元格上手动绘制一些东西。
您要做的是在项目上设置int/float 数据,但显示它们的字符串表示,并允许用户编辑数据。
这通常通过QItemDelegate 完成。这是可以做到的一种方法。
MY_DATA_ROLE = QtCore.Qt.UserRole + 1
INT_TYPE = QtGui.QTableWidgetItem.UserType + 1
FLOAT_TYPE = QtGui.QTableWidgetItem.UserType + 2
class MyFloatIntDelegate(QtGui.QItemDelegate):
def __init__(self, parent, table):
super(MyFloatIntDelegate, self).__init__(parent)
self.table = table
def paint(self, painter, option, index):
item = self.table.itemFromIndex(index)
# This ensures the table is always displaying
# the int/float value stored in the custom data role.
if item and item.text() != str(item.data(MY_DATA_ROLE)):
item.setText(str(item.data(MY_DATA_ROLE)))
super(MyFloatIntDelegate, self).paint(painter, option, index)
def createEditor(self, parent, option, index):
editor = None
item = self.table.itemFromIndex(index)
if item:
# Is this an int item?
if item.type() == INT_TYPE:
editor = QtGui.QSpinBox(parent)
# Set the min/max as appropriate
editor.setRange(0, 100)
# or a float item?
elif item.type() == FLOAT_TYPE:
editor = QtGui.QDoubleSpinBox(parent)
# Set the min/max as appropriate
editor.setRange(0, 100)
return editor
def setEditorData(self, editor, index):
item = self.table.itemFromIndex(index)
if item:
if item.type() == INT_TYPE:
editor.setValue(item.data(MY_DATA_ROLE))
elif item.type() == FLOAT_TYPE:
editor.setValue(item.data(MY_DATA_ROLE))
def setModelData(self, editor, model, index):
item = self.table.itemFromIndex(index)
if item:
item.setData(MY_DATA_ROLE, editor.value())
item.setText(str(editor.value()))
class MyWidget(QtGui.QWidget):
def __init__(self):
...
self.table = QtGui.QTableWiget(self)
self.delegate = MyIntFloatDelegate(self, self.table)
self.table.setItemDelegate(self.delegate)
# Creating Items
vals = [1, 3.5, 6.6, 1.0, 1.0]
row = 0
self.table.setColumnCount(len(vals))
self.table.setRowCount(1)
for col, val in enumerate(vals):
item_type = INT_TYPE if isinstance(val, int) else FLOAT_TYPE
item = QtGui.QTableWidgetItem(item_type)
item.setData(MY_DATA_ROLE, val)
self.table.setItem(row, col, item)
# Getting data
vals = []
for col in range(len(vals)):
item = self.table.item(row, col)
val = item.data(MY_DATA_ROLE)
vals.append(val)
您也可以省略使用type 值,而只为每种不同类型子类QTableWidgetItem,并在QItemDelegate 中进行isinstance() 检查,而不是检查type() 值。在这种情况下,您也可以只将int/float 值存储为text 数据,而不是创建MY_DATA_ROLE 自定义角色,并在需要数据值时将文本数据来回转换为int/float 值。当然,对于比int/float 值更复杂的数据,通常无法做到这一点,因此使用自定义数据角色(或子类QTableItemWidgets 上的属性)更灵活,可以在更多情况下使用。