model.set_sort_column_id(SOME_ROW_INDEX, gtk.SORT_ASCENDING)
因此,我想在插入或修改模型时禁用排序,然后重新启用它。很遗憾,不能使用禁用排序
model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
. 使用冻结/解冻功能也不起作用:
treeview.freeze_child_notify()
try:
for row in model:
# ... change something in row ...
finally:
treeview.thaw_child_notify()
那么,如何禁用排序?还是有更好的批量插入/修改方法?
解决方案
感谢bobince在回答中提供的信息和链接,我查看了一些备选方案:
tv.freeze_child_notify()
sortSettings = model.get_sort_column_id()
model.set_default_sort_func(lambda *unused: 0) # <-- can also use None but that is slower!
# model.set_default_sort_func(lambda *unused: 1) <-- slow
# model.set_default_sort_func(lambda *unused: -1) <-- crash (access violation in gtk_tree_store_move_after?!)
model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
# change rows
model.set_sort_column_id(*sortSettings)
tv.thaw_child_notify()
这使时间从11秒降到了2秒。哇!但可能更好,这只是1000排。
2) 更新时删除模型
tv.set_model(None)
# change rows
tv.set_model(model)
3) 虚拟排序和来自
PyGTK FAQ
def gen():
tv.freeze_child_notify()
sortSettings = model.get_sort_column_id()
model.set_default_sort_func(lambda *unused: 0)
model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
i = 0
for row in rowsToChange:
i += 1
# change something
if i % 200 == 0:
# freeze/thaw not really necessary here as sorting is wrong because of the
# default sort function
yield True
model.set_sort_column_id(*sortSettings)
tv.thaw_child_notify()
yield False
g = gen()
if g.next(): # run once now, remaining iterations when idle
gobject.idle_add(g.next)
结果:与解决方案1中估计的2秒相同),但GUI在这段时间内会做出反应。我更喜欢这种方法。如果需要的话,可以调整模200以使GUI或多或少具有反应性。
gtk.TreeStore
为了得到更好的结果?我还没试过,但选项3)现在已经足够了。