我有一个自定义的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
引用,这是我无法获得的,因为它不存在任何更多。也许我在这里采取了一种完全错误的方法,那么最好的方法是什么呢?
答案 0 :(得分:2)
想出来:通过删除子树的根节点行(通知模型路径已经消失并有条件地切换parent.has_child),删除子树可以正常工作。插入新子树同样如此,所以我不需要递归地告诉模型。
然而,这种组合至关重要,所以
答案 1 :(得分: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”可以完美地显示您需要的内容。
希望这能解决你的任务!