сравнение pygtk GtkTreeIter - PullRequest
1 голос
/ 20 мая 2011

У меня есть 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 для последующего обновления?

Ответы [ 2 ]

0 голосов
/ 20 мая 2011

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

  1. Базовый объект данных, представленный в каждой строке, является экземпляром GObject
  2. Этот GObject подкласс обладает рядом свойств
  3. Когда свойство изменяется, оно испускает сигнал notify::myproperty

В то же время:

  1. My ListStore хранит эти объекты и использует метод gtk.TreeViewColumn.set_cell_data_func() для визуализации каждого столбца (см. Примечание ниже)
  2. Для каждого объекта / строки мой объект, управляющий TreeView, подключается к notify::myproperty
  3. Функция, связанная с этим сигналом 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 заставляет строку перепроверять свою информацию каждый раз, когда происходит перерисовка, поэтому базовая функция должна быть просто функцией поиска, а не интенсивными вычислениями. Практически говоря, из-за этого вы можете избежать процедуры «connect-to-signal / emit-row-change», но лично я чувствую себя лучше, зная, что не будет никаких крайних случаев.

0 голосов
/ 20 мая 2011

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

ОБНОВЛЕНИЕ: Вы можете просто позвонить set_value с недействительным iter. gtk выдаст вам предупреждение, но не выдаст исключение или что-либо еще. В любом случае, он просто проверяет, действительно ли он действителен.

...