由于排序,GtkTreeView插入/更新性能损失

And*_*Dog 6 gtk pygtk bulkinsert gtktreeview

将很多行插入到GTK树视图中时(使用PyGTK)或修改多行时,我遇到了性能问题.问题是模型似乎在每次更改(插入/修改)后都会使用.这会导致GUI挂起多秒钟.通过注释将模型保留为未排序可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()
Run Code Online (Sandbox Code Playgroud)

那么,我怎样才能禁用排序?或者有更好的批量插入/修改方法吗?


感谢他在答案中提供的信息和链接,我检查了一些替代方案:

1)虚拟分拣

 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()
Run Code Online (Sandbox Code Playgroud)

这使得时间从大约11秒减少到2秒.哇!但可能会更好,这只是1000行.

2)更新时删除模型

tv.set_model(None)
# change rows
tv.set_model(model)
Run Code Online (Sandbox Code Playgroud)

没有明显的区别,11秒.

3)Dummy排序和PyGTK常见问题解答中的酷发生器技巧

 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)
Run Code Online (Sandbox Code Playgroud)

结果:与解决方案1)相同的估计2秒,但GUI在此期间作出反应.我更喜欢这种方法.如果需要,可以调整模200以使GUI具有或多或少的反应性.

也许它甚至可以子类化gtk.TreeStore以获得更好的结果?还没有尝试过,但选项3)现在已经足够好了.

bob*_*nce 2

听起来你已经快到了。请参阅常见问题解答以获取更多说明。特别是,您还应该设置default_sort_order(您现在可以None在该示例中使用虚拟比较 lambda,以获得更好的性能)以确保不进行排序,并在操作期间从树视图中删除模型。

如果有很多更改,您最好创建并设置一个完整的新模型。