pythonsortinggtkpygtkgtktreeview

Sort a gtk.TreeColumn by date value


I have a gtk.ListStore attached to a gtk.Treeview

The first column of this gtk.ListStore is of str type and contains a date value (dd/mm HH:MM:SS)

I want to sort the first gtk.TreeviewColumn by date so, I have wrote :

listStore = gtk.ListStore(str, str, str, str, str, str, str, str)
treeview = gtk.TreeView()
treeview.set_model(listStore)

cell = gtk.CellRendererText()
column = gtk.TreeViewColumn('Date', cell, text=0)
column.set_sort_column_id(0)
treeview.append_column(column)

But the sorting doesn't works fine : It sort by day, not by date.

How can I do to make the sorting by date ?

Thanks

EDIT :

To make the sorting easier, the month value is stored as number (From 01 to 12).


Solution

  • I have found a solution by using the Gtk.TreeSortable.set_sort_func() :

    listStore = gtk.ListStore(str, str, str, str, str, str, str, str)
    listStore.set_sort_func(0, date_compare, None)
    treeview = gtk.TreeView()
    treeview.set_model(listStore)
    
    cell = gtk.CellRendererText()
    column = gtk.TreeViewColumn('Date', cell, text=0)
    column.set_sort_column_id(0)
    treeview.append_column(column)
    ...
    

    And I have wrote my date_compare function :

    (Maybe it have a most elegant manner to wrote this date_compare function : I would be happy to hear yours :-))

    def date_compare(model, row1, row2, user_data):
        # Returns : 
        # - a negative integer if iter1 sorts before iter2,
        # - zero if they are equal,
        # - a positive integer if iter2 sorts before iter1.
    
        sort_column, _ = model.get_sort_column_id()
        date1 = model.get_value(row1, sort_column)
        date2 = model.get_value(row2, sort_column)
    
        # We split the date string to an array : 
        #  0  |   1   |   2  |    3    |    4
        # day | month | hour | minutes | seconds
        values1 = re.split("[ /:]", date1)
        values2 = re.split("[ /:]", date2)
    
        if values1[1] < values2[1] :
            return -1
        elif values1[1] == values2[1] : # same month => we compare by day
            if values1[0] < values2[0] :
                return -1
            elif values1[0] == values2[0] : # same month and day => we compare by hour
                if values1[2] < values2[2] :
                    return -1
                elif values1[2] == values2[2] : # same month, day and hour => we compare by minute
                    if values1[3] < values2[3] :
                        return -1
                    elif values1[3] == values2[3] : # same month, day, hour and minute => we compare by second
                        if values1[4] < values2[4] :
                            return -1
                        elif values1[4] == values2[4] : # same month, day, hour, minute and second => it's same date !
                            return 0
                        else :
                            return 1
                    else :
                        return 1
                else :
                    return 1
            else :
                return 1
        else :
            return 1