1

I am trying to limit the amount of decimal places shown in a Gtk.CellRendererText. Currently a float number field is shown with 6 decimal places, but I would like to have just 1.

enter image description here

This test code should work on Linux:

#!/usr/bin/python3
from gi.repository import Gtk

class MyWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Hello World")
        self.set_default_size(200, 200)

        self.liststore = Gtk.ListStore(float)
        treeview = Gtk.TreeView(model=self.liststore)

        self.liststore.append([9.9])
        self.liststore.append([1])

        xrenderer = Gtk.CellRendererText()
        xrenderer.set_property("editable", True)
        xcolumn = Gtk.TreeViewColumn("Float Numbers", xrenderer, text=0)
        xcolumn.set_min_width(100)
        xcolumn.set_alignment(0.5)
        treeview.append_column(xcolumn)

        self.add(treeview)

win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
tobias47n9e
  • 2,233
  • 3
  • 28
  • 54

3 Answers3

7

Tripped over the same problem. Basically what you want to do is use your GtkTreeViewColumn's set_cell_data_func to set the rendering function, which changes the 'text' property of the cell. In terms of your example, try adding the line:

xcolumn.set_cell_data_func(xrenderer, \
    lambda col, cell, model, iter, unused:
        cell.set_property("text", "%g" % model.get(iter, 0)[0]))

References:

lyngvi
  • 1,312
  • 12
  • 19
  • I am now using string formatting for all my treeviews, but that looks like a nice solution too. – tobias47n9e Jan 30 '15 at 20:18
  • 1
    This is a pretty good solution, tho it would be nicer if you could use the lambda function more generally. so instead of doing: model.get(iter, 0). It would be nice to be able to have it just figure out the index value: model.get(iter, index). I could not figure out how to do this tho. – zeitue Mar 28 '19 at 00:01
2

Building on the above for a 2 digit Money renderer. We pass the text=3 liststore index as the func_data (it's the unused parameter lyngvi used).

I'm not certain how to read the "digits" property from the cell renderer yet to make this code reuseable for any number of digits, but this works for money. I might refactor it for generic string formatting too.

https://developer.gnome.org/pygtk/stable/class-gtktreeviewcolumn.html#method-gtktreeviewcolumn--set-cell-data-func

class MoneyCellRenderer(Gtk.CellRendererSpin):
    def __init__(self):
        super().__init__()
        self.set_property("editable", True)
        self.set_property("digits", 2)
        adjustment = Gtk.Adjustment(0, 0, sys.maxsize, 0.01, 1.00, 1.00)
        self.set_property("adjustment", adjustment)

# Only show 2 digits
# https://stackoverflow.com/questions/27675919/how-to-limit-number-of-decimal-places-to-be-displayed-in-gtk-cellrenderertext
# https://developer.gnome.org/pygtk/stable/class-gtktreeviewcolumn.html#method-gtktreeviewcolumn--set-cell-data-func
def moneyCellDataFunc(treeViewColumn, cellRenderer, model, iter, column):
    val = model.get(iter, column)
    val = val[0]
    val = "{:.2f}".format(val) # TODO get cell_rendere.digits
    return cellRenderer.set_property("text", val)

class MoneyTreeViewColumn(Gtk.TreeViewColumn):
    def __init__(self, title, cell_renderer, text=0):
        super().__init__(title, cell_renderer, text=text)
        self.set_cell_data_func(cell_renderer, moneyCellDataFunc, text)
Zren
  • 759
  • 7
  • 13
0

Thanks to lyngvi I am now using this slightly modified code to round and truncate the values in the treeview to one decimal place:

    def truncate(self, number):
        """
        Rounds and truncates a number to one decimal place. Used for all
        float numbers in the data-view. The numbers are saved with full float
        precision.
        """
        number = round(number, 1)
        return number

    renderer_dir = Gtk.CellRendererText()
    renderer_dir.set_property("editable", True)
    column_dir = Gtk.TreeViewColumn("Dir", renderer_dir, text=0)
    column_dir.set_alignment(0.5)
    column_dir.set_expand(True)
    column_dir.set_cell_data_func(renderer_dir, \
                lambda col, cell, model, iter, unused:
                cell.set_property("text",
                "{0}".format(self.truncate(model.get(iter, 0)[0]))))
    self.append_column(column_dir)
Community
  • 1
  • 1
tobias47n9e
  • 2,233
  • 3
  • 28
  • 54