Как получить GtkTreePath или GtkTreeIter для последней строки в GtkTreeModel? - PullRequest
3 голосов
/ 24 мая 2010

Я хочу получить GtkTreePath или GtkTreeIter для последней строки в GtkTreeModel, но GtkTreeModel не имеет функции для этого.

Я буду рад ответам и примерам в C, Python или обоих;).

Ответы [ 4 ]

3 голосов
/ 24 мая 2010

Вы должны быть в состоянии пройти через 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);

Примечание: я не проверял вышеизложенное, как я написал, но яЯ уверен, что я сделал что-то очень похожее в реальном коде.

2 голосов
/ 14 августа 2011

Спасибо за все предыдущие ответы, однако я считаю, что окончательное решение должно включать то, что TreeModel (с TreeStore) может хранить элементы со многими уровнями вложенности (например, путь (2,0,4,2)). Решение, опубликованное «fresh», не сработало для меня, так как мне нужна была функция, которая будет корректно проходить через всех последних детей, пока она действительно не найдет последний ряд. Ниже мое окончательное решение:

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

Или даже более короткая форма:

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
2 голосов
/ 26 мая 2010

Несмотря на то, что ответ размотки был верным и достаточным, чтобы поставить меня на правильный путь, я решил добавить свои окончательные решения просто ради полноты:

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;
}
1 голос
/ 24 мая 2010

Вот как я это делаю сейчас, но это кажется неуклюжим ...

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
...