сравнение pygtk GtkTreeIter

1

У меня есть ListStore в PyGTK, у которого есть куча строк. Существует фоновое задание, обрабатывающее данные, представленные строками, и когда он заканчивается, ему необходимо обновить строку. Конечно, для этого нужно знать, какую строку обновить, и, таким образом, сохранить итератор в строке вокруг. Тем не менее, во время жизненного цикла фона пользователь может удалить строку. Это нормально - мы просто заменяем сохраненный итератор "None", и фоновая работа продолжается весело. Проблема в том, что при удалении строки итераторы не сравниваются как равные, и ничто не становится равным None. На самом деле, нет двух итераторов AFAIK, сравните их. Проблема в минимальном примере такова:

>>> store = gtk.ListStore(int)
>>> store.insert(1)
<GtkTreeIter at 0x1d49600>
>>> print store[0].iter == store[0].iter
False

Ложь, но они же итератор! (Я знаю, что они разные экземпляры, но они представляют одно и то же, и они определяют метод __eq__.) Что мне здесь не хватает и как отслеживать строки в ListStore для последующего обновления?

Теги:
gtk
pygtk

2 ответа

0

Я бы подошел к этому по-другому - вот что я сделал в подобной ситуации:

  • Основным объектом данных, представленным в каждой строке, является экземпляр GObject
  • В этом подклассе GObject есть куча свойств
  • Когда свойство изменяется, оно выдает сигнал notify::myproperty

В то же время:

  • My ListStore хранит эти объекты и использует метод gtk.TreeViewColumn.set_cell_data_func() для отображения каждого столбца (см. примечание ниже).
  • Для каждого объекта/строки мой объект, управляющий TreeView, подключается к notify::myproperty
  • Функция, связанная с этим сигналом notify::..., вызывает сигнал row-changed на ListStore

Некоторые коды:

def on_myprop_changed(self, iter, prop):
    path = self.model.get_path(iter)
    self.model.row_changed(path ,iter)

def on_thing_processed(self, thingdata):
    # Model is a ListStore
    tree_iter = self.model.append((thingdata,))

    # You might want to connect to many 'notify::...' signals here,
    # or even have your underlying object emit a single signal when
    # anything is updated.
    hid = thingdata.connect_object('notify::myprop',
                                   self.on_myprop_changed,
                                   tree_iter)
    self.hids.add((thingdata, hid))

Я сохраняю скрытые объекты в списке, чтобы я мог отключить их, когда таблица очищена. Если вы позволите удалить отдельные строки, вам, вероятно, потребуется сохранить их на карте (путь → скрыть, или объект → скрыть).

Примечание. Необходимо помнить, что set_cell_data_func заставляет строку повторно проверять свою информацию каждый раз при перерисовке, поэтому базовая функция должна быть просто функцией поиска, а не интенсивным вычислением. Практически говоря, из-за этого вы можете уйти от того, чтобы не выполнять процедуру "подключение к сигналу/испусканию строки", но лично я чувствую себя лучше, зная, что не будет никаких случаев с краями.

0

Попробуйте использовать метод хранения списка .get_path(iter) и сравните результирующие пути вместо сравнения итераторов напрямую.

UPDATE: вы можете просто вызвать set_value с недопустимым iter. gtk предоставит вам предупреждение, но не исключит ничего. Вероятно, он просто проверяет, действительно ли он действительный итер.

  • 0
    Согласно документам, «этот метод медленный. Используйте его только для целей отладки и / или тестирования», поэтому я надеялся избежать этого. (Я мог бы сделать управление итератором за O (1) раз ... если бы они сравнили должным образом.)
  • 0
    @Tanatos: да я видел то же самое и обновил свой ответ
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню