The solution is to use a delegate and override the paint method that is responsible for showing what looks in normal state, I have built the following class based on the above.
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)
In your case you should use it as follows:
self.TableWidget.setItemDelegate(FloatDelegate(3))
Example:
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_())
Screenshots:
Plus:
By Row o Column:
#only column 2
setItemDelegateForColumn(2, FloatDelegate(3))
#only row 2
setItemDelegateForRow(2, FloatDelegate(3))
If you want to apply only to cell 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)
Update:
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)