[pygtk] sorting a treeview/liststore

John Hunter jdhunter at ace.bsd.uchicago.edu
Wed Sep 6 21:19:24 WST 2006


I have a liststore that I am trying to sort by clicking on the columns
in treeview.  I have registered some sort funcs by column but am not
getting the desired result.  Everytime I click a column, it seems like
the sort order is permuted, but I expect it to be lexically sorted.
Eg, if I click on the "Symbol" column, I expect the rows in this sort order 


  ['AAA', 'JDH', 'MKA', 'RHA', 'ZZZ']

Here is a complete example:

import sys, random

import pygtk
pygtk.require("2.6")
import gobject, gtk, pango
import gtk.glade

class Deltas(gtk.ScrolledWindow):
    COLSYMBOL, COLPRICE, COLPCT  = range(3)
    def __init__(self):
        gtk.ScrolledWindow.__init__(self)


        self.seq = None # not initialized with accts
        self.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        self.set_policy(gtk.POLICY_NEVER,
                        gtk.POLICY_AUTOMATIC)
        
        model = self.model = gtk.ListStore(
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            )

                    
        treeview = gtk.TreeView(self.model)
        treeview.show()
        treeview.set_rules_hint(True)

        
        def sort0(liststore, iter1, iter2):
            val1 = model.get_value(iter1, 0)
            val2 = model.get_value(iter2, 0)
            print 'sort0', val1, val2, val1<val2
            return val1<val2

        def sort1(liststore, iter1, iter2):
            val1 = model.get_value(iter1, 1)
            val2 = model.get_value(iter2, 1)
            print 'sort1', val1, val2, val1<val2            
            return val1<val2

        def sort2(liststore, iter1, iter2):
            val1 = model.get_value(iter1, 2)
            val2 = model.get_value(iter2, 2)
            print 'sort2', val1, val2, val1<val2
            return val1<val2
            
        columns = (('Symbol',sort0),
                   ('Price',sort1),
                   ('Pct',sort2),
                   )

        class Clicked:
            def __init__(self, i):
                self.i = i
                self.func = columns[i][1]

            def __call__(self, column):
                print 'column clicked', self.i
                model.set_sort_column_id(self.i,gtk.SORT_ASCENDING)
                model.set_sort_func(self.i, self.func)
        
        for i in range(len(columns)):
            renderer = gtk.CellRendererText()
            column = gtk.TreeViewColumn(columns[i][0], renderer, text=i)
            renderer.set_property('xalign', 1.)
            column.connect('clicked', Clicked(i))
            column.set_property('clickable', True)
            treeview.append_column(column)


        self.add(treeview)
        self.treeview = treeview

        self.model.clear()
        self.iterd = dict()   # a dict from symbol -> iter
        
        for sym in 'ZZZ', 'AAA', 'JDH', 'MKA', 'RHA':
            self.add_row(sym, random.random(), 100*random.random())
            
    def add_row(self, symbol, price, pct):
        thisiter = self.model.append()        
        
        self.model.set(thisiter,
                       self.COLSYMBOL, symbol,
                       self.COLPRICE, '%1.3f'%price,
                       self.COLPCT, '%1.1f'%pct)
        self.iterd[symbol] = thisiter

        
deltawin = Deltas()
deltawin.show()

win = gtk.Window()
win.show()
win.add(deltawin)
gtk.main()


More information about the pygtk mailing list