3

我有一个自定义的 GenericTreeModel,效果很好。现在我希望用户能够使用拖放重新排列节点,因此我将节点移动到数据模型中的新父节点。但是,TreeModel 希望使用row_has_child_toggled,row_deleted和等方法得到通知row_inserted

所以显然没有row_moved和调用row_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) )也会发生,但是该行 a) 已被删除并且 b)row_has_child_toggled需要一个tree_iter引用,我无法得到它,因为它不再存在。

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

4

2 回答 2

2

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

但是组合很关键,所以

  1. 首先删除,通知模型
  2. 然后再次插入并通知模型。
于 2011-09-09T10:32:38.393 回答
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”可以完美地向您展示您的需求。

希望这能解决您的问题!

于 2011-09-06T09:03:43.057 回答