2011-09-06 78 views
3

我有一个自定义的GenericTreeModel,工作得很好。现在我希望用户能够使用拖放来重新排列节点,所以我将节点移动到数据模型中的新父节点。 然而,TreeModel希望使用像row_has_child_toggled,row_deletedrow_inserted这样的方法来通知。如何在移动子树后更新TreeModel

所以显然没有row_movedrow_deleted(原路径)和row_inserted(新路径)似乎是不够的。所以我想我可能不得不递归地发布这些更改。

请看下面的例子:

* A (0,) 
* B (1,) 
    * C (1,0) 
    * D (1,0,0) 

现在,如果我搬到C到A,下面的事情发生了:

row_delete((1,0)) # C 
row_delete((1,0,0)) # D 
row_inserted((0,0)) # C' 
row_inserted((0,0,0)) # D' 
child_toggle((0,)) # A 
child_toggle((1,)) # B 
child_toggle((0,1)) # C' 

然而,GTK仍抱怨模型不一致的状态。两件事情都在我的脑海:

  • 也许调用这些函数的顺序是相关的(?如果是的话任何想法如何)
  • 技术上child_toggle((1,0))也发生了,但是该行一)已经被删除和b)row_has_child_toggled需要一个tree_iter参考,我不能得到,因为它不再存在。

也许我在这里采取了完全错误的方法,那么最好的方法是什么?

回答

2

想出来:删除子树通过删除子树的根节点行(通知模型路径消失并有条件地切换parent.has_child)可以正常工作。插入一个新的子树也是一样,所以我不需要递归地告诉模型的东西。

然而所述组合是关键的,所以

  1. 首先删除,通知模型
  2. 然后插入并再次通知模型。
1

恕我直言,这个更新将自动为树状,如果你与它的“drag_data_get”和“drag_data_received”方法正确连接树状发生,并允许它是一个源和它的“enable_model_drag_dest”和“enable_model_drag_source”目标方法。 树形视图应该没有更多的事情要做。

模型必须在调用它的“drag_data_received_data”被更新,但没有“删除”做的,只是具体的“insert_before”或“insert_after”如下所示:

def drag_data_received_data(self, treeview, context, x, y, selection, 
           info, etime): 
     model = treeview.get_model() 
     data = selection.data 
     drop_info = treeview.get_dest_row_at_pos(x, y) 
     if drop_info: 
      path, position = drop_info 
      iter = model.get_iter(path) 
      if (position == gtk.TREE_VIEW_DROP_BEFORE 
       or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE): 
       model.insert_before(iter, [data]) 
      else: 
       model.insert_after(iter, [data]) 
     else: 
      model.append([data]) 
     if context.action == gtk.gdk.ACTION_MOVE: 
      context.finish(True, True, etime) 
     return 

这片段来自:

http://www.pygtk.org/pygtk2tutorial/sec-TreeViewDragAndDrop.html#DragDropReordering

在节目“treeviewdnd.py”完美的作品来告诉你,你需要什么。

希望这能解决您的任务!

+0

这对于gtk.TreeStore是正确的,但是gtk.GenericTreeModel不支持insert_after/before函数。所以我必须执行它们,不幸的是我会回到我的问题。 – rumpel

相关问题