Re: [pygtk] Filtered Sortable

2011-02-18 Thread Timo

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. I 
recently implemented this in my app too.


As far as I know, it is the lowest model, the liststore. 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. 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.


Cheers,
Timo

[1] 
http://library.gnome.org/devel/pygtk/stable/class-gtktreesortable.html#method-gtktreesortable--set-sort-func



[that is the model directly owned by the view.

Does anyone have a working example of a filtered sortable list?

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


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


Re: [pygtk] Filtered Sortable

2011-02-18 Thread Adam Tauno Williams
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/


Re: [pygtk] Filtered Sortable

2011-02-18 Thread Adam Tauno Williams
On Fri, 2011-02-18 at 06:27 -0500, Adam Tauno Williams wrote: 
 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)
 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

Perhaps it is doing the same stupid thing as the sort call and trying to
set the column sort id on the TreeModelFilter?

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


Re: [pygtk] Filtered Sortable [SUCCESS!]

2011-02-18 Thread Adam Tauno Williams
On Fri, 2011-02-18 at 06:27 -0500, Adam Tauno Williams wrote: 
 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)

Okay, I figured it out.

The call to set_default_sort_func(TaskList.sort, None) is *wrong*.  [It
makes sense, and is obvious, but wrong].  Setting a sort function and
retrieving the sort column in the sort method just isn't how Gtk works.
You have to see a sort function for each sortable column and pass the
column id either implicitly [a different sort function for every column]
or explicitly [by using the user_data] field.

So, something like...

class TaskList(object)
...
@staticmethod
def sort_model(model):
sortable = gtk.TreeModelSort(model)
sortable.set_sort_func(TaskList.COLUMN_TASK_ID, 
   TaskList.sort, 
   TaskList.COLUMN_TASK_ID)
sortable.set_sort_func(TaskList.COLUMN_TASK_NAME,
   TaskList.sort, 
   TaskList.COLUMN_TASK_NAME)

sortable.set_sort_func(TaskList.COLUMN_TASK_END, 
   TaskList.sort, 
   TaskList.COLUMN_TASK_END)
sortable.set_sort_column_id(TaskList.COLUMN_TASK_ID,
gtk.SORT_ASCENDING)
return sortable

- then in the sort function -

@staticmethod
def sort(model, iter1, iter2, user_data):
sort_by = user_data
value1 = model[iter1][0][TaskList.COLUMN_KEYS[sort_by]]
value2 = model[iter2][0][TaskList.COLUMN_KEYS[sort_by]]
return cmp(value1, value2)

I know have a sortable filtered TreeView.

I believe setting a set_default_sort_func might supress the stray -

Warning: unable to set property `text' of type `gchararray' from value
of type `PyObject'

- seen when the application starts.  But I haven't tried that.

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


[pygtk] Filtered Sortable

2011-02-17 Thread Adam Tauno Williams
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?
[that is the model directly owned by the view. 

Does anyone have a working example of a filtered sortable list?

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