如何获取GtkTreeModel最后一行的GtkTreePath或GtkTreeIter?

5 投票
4 回答
4647 浏览
提问于 2025-04-15 23:04

我想获取一个GtkTreePath或GtkTreeIter,指向GtkTreeModel中的最后一行,但GtkTreeModel没有提供这样的功能。

我很高兴看到用C语言、Python语言,或者两者都有的回答和例子;)。

4 个回答

2

这是我目前的做法,但感觉有点笨拙...

C语言的例子:

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语言的例子:

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

虽然unwind的回答是正确的,并且足以让我走上正轨,但我觉得为了完整起见,我还是想分享一下我的最终解决方案:

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;
}
4

你可以尝试使用GtkTreePath,这可能有点像小技巧,但还是在这个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);

注意:我没有实际测试上面的代码,不过我很确定我在真实代码中做过类似的事情。

撰写回答