开发者

How do I get a GtkTreePath or GtkTreeIter to the last row in a GtkTreeModel?

I want to get a GtkTreePath or GtkTreeIter to the last row in a GtkTreeModel, bu开发者_开发技巧t GtkTreeModel does not have a function for that.

I'll be happy with answers and examples in either C, or Python, or both ;).


You should be able to go through a GtkTreePath, a bit of a hack maybe but still within the API:

GtkTreePath *path;
GtkTreeIter iter;

/* With NULL as iter, we get the number of toplevel nodes. */
gint rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(model), NULL);

/* Now get a path from the index. */
path = gtk_tree_path_new_from_indices(rows - 1, -1);

/* Ask the model for an iter to the node identified by the path. */
gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);

/* Drop the path, we're done with it, iter is final output. */
gtk_tree_path_free(path);

Note: I haven't tested the above as I wrote it, but I'm pretty sure I've done something very similar in real code.


Even though unwind's answer was correct and enough to put me on the right track, I thought I'd add my final solutions just for completeness' sake:

Python:

def model_get_iter_last( model, parent=None ):
  """Returns a gtk.TreeIter to the last row or None if there aren't any rows.
  If parent is None, returns a gtk.TreeIter to the last root row."""
  n = model.iter_n_children( parent )
  return n and model.iter_nth_child( parent, n - 1 )

C:

/**
 * Set itr_last to last item of parent if parent has any rows.
 * If parent is NULL, set itr_last to last root row.
 * Returns TRUE if itr_last could be set, otherwise FALSE.
 */
gboolean model_get_iter_last( GtkTreeModel *model,
                              GtkTreeIter *itr_last,
                              GtkTreeIter *parent )
{
  gboolean success;
  gint n;

  if ( n = gtk_tree_model_iter_n_children( model, parent ) ) {
    success = gtk_tree_model_iter_nth_child( model, itr_last, parent, n - 1 );
  }
  else {
    itr_last = NULL;
    success = FALSE;
  }
  return success;
}


Here is how I do it currently, but it seems clumsy...

C example:

void get_iter_last( GtkTreeModel *mdl, GtkTreeIter *itr )
{
  GtkTreeIter i;
  if ( gtk_tree_model_get_iter_first( mdl, &i ) ) {
    while ( gtk_tree_model_iter_next( mdl, &i ) ) {
      *itr = i;
    }
  }
}

Python example:

def get_iter_last( mdl ):
  itr = mdl.get_iter_first()
  last = None
  while itr:
    last = itr
    itr = mdl.iter_next( itr )
  return last


Thanks for all previous answers, however I believe that final solution should include that TreeModel (with TreeStore) can store items with many levels of nesting (eg. path (2,0,4,2)). Solution posted by 'fresh' didn't worked for me, as I needed a function that will properly traverse thru all of the last children, until it really finds last row. Below is my final solution:

def get_last_iter (self, model):
    n = model.iter_n_children (None)
    # list empty
    if n == 0:
        return None
    else:
        iter = model.iter_nth_child (None, n - 1)
        n = model.iter_n_children (iter)
        # last top-level item has no children, so select that last item
        if n == 0:
            return iter
        else:
            # traverse thru every last child
            while 1:
                iter = model.iter_nth_child (iter, n - 1)
                n = model.iter_n_children (iter)
                if n == 0:
                    return iter

Or even shorter form:

def get_last_iter (self, model):
    iter = None
    n = 0
    while 1:
        iter = model.iter_nth_child (iter, n - 1)
        n = model.iter_n_children (iter)
        if n == 0:
            return iter
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜