我在PyGTK中有一个ListStore,它有一堆行。有一个后台作业处理由行表示的数据,当它完成时,它需要更新该行。当然,要做到这一点,它需要知道要更新的哪个行,并因此保持对该行的迭代器。但是,在后台作业生命期间,用户可能会删除该行。这没关系 - 我们只是用“None”替换存储的迭代器,后台工作继续快乐。问题是当删除行时,迭代器不会相等,并且没有任何内容设置为None。实际上,没有两个迭代器,AFAIK,比较相等。在最小的例子中,问题是:
>>> store = gtk.ListStore(int)
>>> store.insert(1)
<GtkTreeIter at 0x1d49600>
>>> print store[0].iter == store[0].iter
False
错,但它们是相同的迭代器! (我知道它们是不同的实例,但它们代表相同的东西,它们定义了__eq__
方法。)我在这里缺少什么,如何跟踪ListStore中的行以便以后更新?
答案 0 :(得分:0)
尝试使用列表存储的.get_path(iter)
方法,并比较结果路径,而不是直接比较迭代器。
更新:您只需使用无效set_value
来致电iter
即可。 gtk
会给你一个警告,但不会抛出异常或任何东西。它可能只是检查它是否是一个有效的iter。
答案 1 :(得分:0)
我会采用不同的方法 - 这就是我在类似情况下所做的事情:
GObject
GObject
子类具有一堆属性notify::myproperty
信号同时:
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))
我将hids保存在列表中,以便在清除表时可以断开它们。如果您删除单个行,则可能需要将它们存储在地图中(路径 - &gt; hid或object - &gt; hid)。
注意:你需要记住set_cell_data_func
导致每次重绘时行重新检查其信息,因此底层函数应该只是一个查找函数,而不是密集计算。实际上,正因为如此,你可以不做“连接到信号/发射行改变”的程序,但我个人觉得更好,因为不会有任何边缘情况。