On Fri, 2011-02-18 at 10:13 +0100, Timo wrote: 
> On 17-02-11 21:08, Adam Tauno Williams wrote:
> > I'm confused trying to make a filtered&  sorted treeview.  Filtering
> > works... data is correctly displayed.  But sorting does not work.
> >
> > self.todo_model = gtk.ListStore(gobject.TYPE_PYOBJECT)
> > # Create a TreeModelFilter to control row visibility
> > self.todo_filter = self.todo_model.filter_new()
> > self.todo_filter.set_visible_func(self.todo_visible_filter)
> > # Create a TreeModelSort to wrap the TreeModelFilter
> > self.todo_sort = gtk.TreeModelSort(self.todo_filter)
> > # Set a sort function
> > self.todo_sort.set_default_sort_func(TaskList.sort, None)
> > # Set the model in the view to the TreeModelSort
> > self.todo_task_view.set_model(self.todo_sort)
> >
> > TaskList.sort ---
> >      @staticmethod
> >      def sort(model, iter1, iter2, user_data):
> >          print 'SORT', model, iter1, iter2
> >          sort_by = model.get_sort_column_id()
> >
> > This fails because model is a TreeModelFilter... which does not have a
> > method get_sort_column_id.... why isn't this the TreeModelSort object?
> NOTE: Using a sorted filter can be very confusing in the beginning.

Yep.

> As far as I know, it is the lowest model, the liststore.

?  I'm sorry, but I don't follow.  What is "it" [is the lowest model]?

> Your setup 
> looks good, it is the sort function that is not good. The docs [1] say 
> that the function should return -1, 0 or 1.

Which my function does; I just didn't include beyond the call to
get_sort_column_id because the method call *fails* at that point because
the model is a TreeModelFilter which does *not* have a
get_sort_column_id method. 

If I just don't call get_sort_column_id and assume a static sort column
then I do get some sorting behavior [although not correct, at least
something happens if I click on the header of the first column].

If I build a hack and drive down to the lowest model (the actual
ListStore) -

        initmodel = model
        basemodel = None
        while basemodel is None:
            if (isinstance(model, gtk.TreeModelFilter)):
                model = model.get_model()
            elif (isinstance(model, gtk.TreeModelSort)):
                model = model.get_model()
            else:
                basemodel = model
sort_by = basemodel.get_sort_column_id()

Then sort_by ends up being (None, None).

IMO, this is a bit beyond confusing.  Searching archives I've found
several posts about this issue... and never an answer.

Clicking on the header of a column other than the first column just
results in an error of -

GtkWarning: gtk_tree_model_sort_set_sort_column_id: assertion `header !=
NULL' failed

> Here is the method I use:
>      def _sort_func(self, model, iter1, iter2):
>          data1 = model.get_value(iter1, 3)
>          data2 = model.get_value(iter2, 3)
>          if data1 == data2:
>              data1 = model.get_value(iter1, 2)
>              data2 = model.get_value(iter2, 2)
>          return cmp(data1, data2)
> This will sort column 2 if the values in column 3 are equal. The key 
> part here is the built-in cmp() function that will return -1, 0 or 1, 
> which is what we need.


_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to