Как использовать стандартные итераторы dict / list с python gtk GenericTreeModel? - PullRequest
2 голосов
/ 21 марта 2012

У меня есть своя собственная структура данных древовидной структуры в памяти, и я хочу использовать gtk GenericTreeModel для ее отображения.На некоторых уровнях в моем дереве есть словари, на некоторых других уровнях списки.(Я не хочу TreeStore, потому что тогда мне нужно связать / скопировать вещи. Я хочу работать с исходными данными.)

Моя идея - использовать итератор словаря / списка при реализации метода on_get_iter().Для элемента верхнего уровня метод выглядит так (некоторый код пропущен):

def on_get_iter(self, path):
    return self.__my_data.get_dict().iteritems()

Метод on_iter_next() очень прост:

def on_iter_next(self, rowref):
    try:
        return rowref.next()
    except StopIteration:
        return None

Но тогда возникает необходимость получитьданные.Это сделано с on_get_value().Я понятия не имею, как это реализовать:

def on_get_value(self, rowref, column):
    # What to write here?

В документации сказано, что значение текущей строки должно быть возвращено здесь.IMHO 'rowref.next ()' делает не то, потому что он получает не текущий, а следующий элемент.

IMHO нет способа получить доступ к текущему элементу итератора (см. PEP 234).

Есть ли способ использовать GenericTreeModel со стандартными итераторами, такими как словарь или итераторы списка?

Обновление: я нашел обходной путь для этого.Использование следующего итератора вместо стандартных работает для меня;конструктор получает стандартный итератор словаря / списка.

class GTMIterator:

    def __init__(self, iterator):
        self.__iterator = iterator
        self.__current = None
        self.next()

    def next(self):
        try:
            self.__current = self.__iterator.next()
        except StopIteration:
            return None
        return self.__current

    def current(self):
        return self.__current

Но: IMHO, это всего лишь обходной путь, а не «чистое» решение.

Ответы [ 2 ]

0 голосов
/ 03 июля 2014

Один из способов сделать это будет следующим:

def on_get_iter(self, path):
  ...
  iterator = self.__my_data.get_dict().iteritems()
  data = iterator.next()
  return {'iterator': iterator, 'data': data}

def on_iter_next(self, rowref):
  try:
    iterator = rowref['iterator']
    next_data = iterator.next()
    return {'iterator': iterator, 'data': next_data}
  except StopIteration:
    return None

def on_get_value(self, rowref, column):
  key, value = rowref['data']
  return value[column]

Ключевым моментом здесь является то, что функции on_* могут возвращать любой объект пользовательских данных, который они хотят. Этот объект автоматически оборачивается в gtk.TreeIter, используя gtk.GenericTreeModel.create_tree_iter и снова распаковывается при звонке другая функция on_* с использованием gtk.GenericTreeModel.get_user_data.

Следовательно, вместо того, чтобы возвращать только итератор Python, возвращаются ключ и значение последним вызовом next метод может быть сохранен для доступа к нему в случае, если он необходимо при вызове какого-либо другого метода.

0 голосов
/ 22 марта 2012

Вам необходимо реализовать интерфейс GtkTreeModel в вашем объекте хранения данных. GtkTreeview использует в качестве модели любой объект GObject, реализующий этот интерфейс.

Для дальнейших ссылок смотрите Обзор GtkTreeModel, GtkTreeView и друзей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...