Skip to content
Advertisement

GTK – Python Treeview Sort Column Data (File Size – Byte Data)

I have a GTK GUI with Python code. There is a treeview on the GUI. I need to list file sizes on the treeview and sort them by file size by clicking on the column. But it sorts files by using their sizes as string.

What is the common way for sorting this files?

  1. Using string file size values (with a cell function or custom sort function).
  2. Using integer file size values (with a cell function or custom sort function).
  3. Another way?

Here is the simplified code:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

builder = Gtk.Builder()
builder.add_from_file('test1.glade')
window1 = builder.get_object('window1')
treeview1 = builder.get_object('treeview1')

class Signals:
    def on_window1_destroy(self, widget):
        Gtk.main_quit()

file_data = [["file1", 12345],
             ["file2", 1234567890],
             ["file3", 1234567],
             ["file4", 1234]]

# Some code to convert data
# .
# .
# .

file_data_converted = [["file1", "12.3 KB"],
                       ["file2", "1.23 GB"],
                       ["file3", "1.23 MB "],
                       ["file4", "1.23 KB"]]

treestore1 = Gtk.TreeStore(str, str)
piter1 = treestore1.append(None, file_data_converted[0])
piter2 = treestore1.append(None, file_data_converted[1])
piter3 = treestore1.append(None, file_data_converted[2])
piter4 = treestore1.append(None, file_data_converted[3])

treeview1.set_model(treestore1)

for i, column_title in enumerate(["File", "Size"]):
    renderer = Gtk.CellRendererText()
    column = Gtk.TreeViewColumn(column_title, renderer, text=i)
    column.set_sort_column_id(i)
    treeview1.append_column(column)

builder.connect_signals(Signals())
window1.show_all()
Gtk.main()

Here is the Glade file:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="default_width">300</property>
    <property name="default_height">300</property>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkTreeView" id="treeview1">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <child internal-child="selection">
          <object class="GtkTreeSelection"/>
        </child>
      </object>
    </child>
  </object>
</interface>

Software information: Python 3.7, GTK3.

Advertisement

Answer

You need to have a hidden column in the store with the file size as an integer that is used solely for sorting. Here’s an example:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

builder = Gtk.Builder()
builder.add_from_file('gtk.ui')
window1 = builder.get_object('window1')
treeview1 = builder.get_object('treeview1')

class Signals:
    def on_window1_destroy(self, widget):
        Gtk.main_quit()


file_data_converted = [["file1", 12345, "12.3 KB"],
                       ["file2", 1234567890, "1.23 GB"],
                       ["file3", 1234567, "1.23 MB "],
                       ["file4", 1234, "1.23 KB"]]

treestore1 = Gtk.TreeStore(str, int, str)
piter1 = treestore1.append(None, file_data_converted[0])
piter2 = treestore1.append(None, file_data_converted[1])
piter3 = treestore1.append(None, file_data_converted[2])
piter4 = treestore1.append(None, file_data_converted[3])

treeview1.set_model(treestore1)

# file name column
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn('File', renderer, text=0)
column.set_sort_column_id(0)
treeview1.append_column(column)
# file size column
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn('Size', renderer, text=2)
column.set_sort_column_id(1)
treeview1.append_column(column)

builder.connect_signals(Signals())
window1.show_all()
Gtk.main()
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement