[pygtk] Re: Indexing ListStore with iterators

John Finlay finlay at moeraki.com
Mon Jul 30 13:31:39 WST 2007


This looks like a gtk+ bug. I did a quick and dirty conversion of your 
python program to C to verify and it exhibits the same problem. You 
should file a gtk+ bug report.

John

--------------------------------------------------------------------------------------
#include <gtk/gtk.h>

gint sort_func(GtkTreeModel *model,
           GtkTreeIter *iter1,
           GtkTreeIter *iter2)
{
  GtkTreePath *path1, *path2;
  gint int1, int2;
  /* When the next 5 lines are left in place, the iterators are corrupted*/
  path1 = gtk_tree_model_get_path(model, iter1);
  path2 = gtk_tree_model_get_path(model, iter2);
  g_print("%d, %d\n", gtk_tree_path_get_indices(path1)[0],
           gtk_tree_path_get_indices(path2)[0]);
  gtk_tree_path_free(path1);
  gtk_tree_path_free(path2);
  gtk_tree_model_get(model, iter1, 0, &int1, -1);
  gtk_tree_model_get(model, iter2, 0, &int2, -1);
  g_print("%d, %d\n", int1, int2);
  return int1 - int2;
}

int main(int argc,
     char * argv[])
{
  GtkWidget *window;
  GtkTreeModel *model;
  GtkCellRenderer *render;
  GtkTreeViewColumn *col1, *col0;
  GtkTreeView *tree;
  GtkTreeIter iter;

  gtk_init(&argc, &argv);

  model = (GtkTreeModel*)gtk_list_store_new(2, G_TYPE_INT, G_TYPE_INT);
  gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), 1000,
                  (GtkTreeIterCompareFunc)sort_func,
                  NULL, NULL);

  tree = (GtkTreeView*)gtk_tree_view_new_with_model(model);
  gtk_tree_view_set_reorderable(tree, FALSE);

  render = gtk_cell_renderer_text_new();
  col0 = gtk_tree_view_column_new_with_attributes("col0", render, NULL);
  gtk_tree_view_column_add_attribute(col0, render, "text", 0);
  gtk_tree_view_column_set_sort_column_id(col0, 1000);

  render = gtk_cell_renderer_text_new();
  col1 = gtk_tree_view_column_new_with_attributes("col1", render, NULL);
  gtk_tree_view_column_add_attribute(col1, render, "text", 1);
  gtk_tree_view_column_set_sort_column_id(col1, 1);

  gtk_tree_view_append_column(tree, col0);
  gtk_tree_view_append_column(tree, col1);
  gtk_tree_view_set_headers_clickable(tree, TRUE);

  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
  gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, 1, 1, 5, -1);
  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
  gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, 8, 1, 3, -1);
  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
  gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, 2, 1, 6, -1);
  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
  gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, 3, 1, 8, -1);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(tree));
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit),
           NULL);
  gtk_widget_show_all(window);
  gtk_main();
  return 0;
}
--------------------------------------------------------------------------------

Brad Schick wrote:
> Anyone have any ideas on this? If not I may try to get debug builds of
> gtk+ and pygtk going to look for the issue.
>
> Perhaps this is a gtk+ problem. Anyone know if the gtk+ mailing lists
> accept problem reports writing with pygtk? I'm guess not...
>
> -Brad
>
>
> On 7/18/07, Brad Schick <schickb at gmail.com> wrote:
>   
>>> While writing a custom sort function for a gtk.ListStore, I found that
>>> using the provided iterator to access the model doesn't work
>>> correctly....
>>>       
>> I hope I'm not missing some stupid error in my code, but this looks
>> like a bug. In the example below, if you comment out or remove the
>> first print statement in "sort_func", everything works as expected.
>> But if you leave in the print statement and click the first column in
>> the treeview, the sort gets stuck in a loop due to what looks like
>> corrupted iterators.
>>
>> It looks like model.get_path is corrupting the iterators.
>> model.get_string_from_iter does the same thing. I've tried this on
>> both linux and windows under pygtk 2.10.4 with gtk 2.10.11 and python
>> 2.5.1.
>>
>> -------------------------------------------------------
>> #!/usr/bin/env python
>> import pygtk
>> pygtk.require('2.0')
>> import gtk
>>
>> def sort_func( model, iter1, iter2 ):
>>     # When the next line is left in place, the iterators are corrupted
>>     print model.get_path(iter1), model.get_path(iter2)
>>
>>     print model.get_value(iter1, 0), model.get_value(iter2, 0)
>>     result = model.get_value(iter1, 0) - model.get_value(iter2, 0)
>>     return min( max(result, -1), 1 ) #  keep results in range
>>
>>
>> model = gtk.ListStore( int, int )
>> model.set_sort_func( 1000, sort_func )
>>
>> tree = gtk.TreeView( model )
>> tree.set_reorderable( False )
>>
>> render = gtk.CellRendererText()
>> col0 = gtk.TreeViewColumn( 'col0', render )
>> col0.add_attribute( render, "text", 0 )
>> col0.set_sort_column_id(1000)
>>
>> render = gtk.CellRendererText()
>> col1 = gtk.TreeViewColumn( 'col1', render )
>> col1.add_attribute( render, "text", 1 )
>> col1.set_sort_column_id(1)
>>
>> tree.append_column( col0 )
>> tree.append_column( col1 )
>> tree.set_headers_clickable( True )
>>
>> model.append( (1,5) )
>> model.append( (8,3) )
>> model.append( (2,6) )
>> model.append( (3,8) )
>>
>> window = gtk.Window( gtk.WINDOW_TOPLEVEL )
>> window.add( tree )
>> window.connect( "destroy", gtk.main_quit )
>> window.show_all()
>> gtk.main()
>>
>>     
> _______________________________________________
> pygtk mailing list   pygtk at daa.com.au
> http://www.daa.com.au/mailman/listinfo/pygtk
> Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
>   



More information about the pygtk mailing list