QTableWidget 显示某些小数,如 excel

QTableWidget display certain decimals like excel

我的问题是关于 QTableWidget 显示单元格值的方式。

我希望单元格在未编辑时仅显示三位小数,而在双击进行编辑时显示完整值。


我在后台进行计算,然后设置单元格值。

V_D = 3/0.7
self.TableWidget.setItem(0, 0, QTableWidgetItem(str(V_D)))

类似于 excel 格式化单元格以显示特定位数的方式。

完整值:

显示值:

我该怎么做?

解决方案是使用委托并重写负责显示正常状态下外观的 paint 方法,我基于上述构建了以下 class。

class FloatDelegate(QItemDelegate):
    def __init__(self, decimals, parent=None):
        QItemDelegate.__init__(self, parent=parent)
        self.nDecimals = decimals

    def paint(self, painter, option, index):
        value = index.model().data(index, Qt.EditRole)
        try:
            number = float(value)
            painter.drawText(option.rect, Qt.AlignLeft, "{:.{}f}".format(number, self.nDecimals))
        except :
            QItemDelegate.paint(self, painter, option, index)

在您的情况下,您应该按如下方式使用它:

self.TableWidget.setItemDelegate(FloatDelegate(3))

示例:

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    w = QTableWidget()
    w.setColumnCount(8)
    w.setRowCount(8)
    for i in range(w.rowCount()):
        for j in range(w.columnCount()):
            number = (i+1)/(j+1)
            w.setItem(i, j, QTableWidgetItem(str(number)))
    w.setItemDelegate(FloatDelegate(3, w))
    w.show()
    sys.exit(app.exec_())

截图:

加上:

按行 o 列:

#only column 2
setItemDelegateForColumn(2, FloatDelegate(3))
#only row 2
setItemDelegateForRow(2, FloatDelegate(3))

如果您只想应用到单元格 2,3

def paint(self, painter, option, index):
   if index.row() == 2 and index.column() == 3:
        value = index.model().data(index, Qt.EditRole)
        try:
            number = float(value)
            painter.drawText(option.rect, Qt.AlignLeft, "{:.{}f}".format(number, self.nDecimals))
        except :
            QItemDelegate.paint(self, painter, option, index)
    else:
        QItemDelegate.paint(self, painter, option, index)

更新:

  • QStyledItemDelegate:

    from math import log10
    
    class FloatDelegate(QStyledItemDelegate):
        def __init__(self, decimals, parent=None):
            super(FloatDelegate, self).__init__(parent=parent)
            self.nDecimals = decimals
    
        def displayText(self, value, locale):
            try:
                number = float(value)
            except ValueError:
                return super(FloatDelegate, self).displayText(value, locale)
            else:
                precision = log10(number) + 1 + self.nDecimals
                return locale.toString(number, f='f', prec=precision)