Python 使用Gtk.TreeDragSource.drag_data_get()

Python 使用Gtk.TreeDragSource.drag_data_get(),python,gtk,pygobject,Python,Gtk,Pygobject,我有一个简单的Gtk.TreeView,模型是四列的Gtk.ListStore。我希望能够在树视图中拖放行,并在行插入、更改和删除时跟踪这些行,以便实现撤消/重做拖放操作。我正在使用PyGObject 3和Python 3.2 我认为在Gtk.TreeDragSource和Gtk.TreeDragDest接口下使用方法将非常适合我的需要,在我的drag_data_get处理程序中使用Gtk.TreeDragSource.drag_get(),在我的drag_data_received处理程序中使

我有一个简单的Gtk.TreeView,模型是四列的Gtk.ListStore。我希望能够在树视图中拖放行,并在行插入、更改和删除时跟踪这些行,以便实现撤消/重做拖放操作。我正在使用PyGObject 3和Python 3.2

我认为在Gtk.TreeDragSource和Gtk.TreeDragDest接口下使用方法将非常适合我的需要,在我的drag_data_get处理程序中使用Gtk.TreeDragSource.drag_get(),在我的drag_data_received处理程序中使用Gtk.TreeDragDest.drag_data_received()或Gtk.tree_get row_drag_data()。基本上,我试过的是这样的:

def drag_data_get(self, tv, context, selection, target_id, time):
    treeselection = tv.get_selection()
    model, my_iter = treeselection.get_selected()
    path = model.get_path(my_iter)
    result = Gtk.TreeDragSource.drag_data_get(path, selection)

def drag_data_received(self, tv, context, x, y, selection,  info, time):
    result, model, row = Gtk.tree_get_row_drag_data(selection)
    my_iter = model.get_iter(row)
    data = [model.get_value(my_iter, i) for i in range(model.get_n_columns())]
    drop_info = tv.get_dest_row_at_pos(x, y)
    if drop_info:
        path, position = drop_info
        my_iter = model.get_iter(path)
        if (position == Gtk.TreeViewDropPosition.BEFORE
            or position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
            model.insert_before(my_iter, [data])
        else:
            model.insert_after(my_iter, [data])
    else:
        model.append([data])    
    if context.get_actions() == Gdk.DragAction.MOVE|Gdk.DragAction.DEFAULT:
        context.finish(True, True, time)
    return

这非常失败——当Python调用Gtk.TreeDragSource.drag_data_get()时,Python崩溃,我的程序窗口迅速消失。我甚至无法访问drag_data_接收的处理程序。有人能给我指出一些示例代码,说明这些使用TreeDragSource和TreeDragDest接口的方法是如何工作的吗?非常感谢任何帮助

使用
Gtk.tree\u set\u row\u drag\u data(选择、模型、路径)
而不是
result=Gtk.TreeDragSource.drag\u data\u get(路径、选择)会不起作用吗

由于您使用了
Gtk.tree\u get\u row\u drag\u data(selection)
,所以您似乎有一些编辑错误。这两种方法的名称相同,首先使用tv,但没有定义它,例如。另外,您确定我的iter始终有效吗?在获取路径之前,可能会尝试检查。@ergosys这就是在疲倦和沮丧时发布的内容:错误的剪切和粘贴。我现在已经修复了drag\u data\u get()方法的签名。在调用Gtk.TreeDragSource.drag_data_get()之前,我已经检查了我在drag_data_get()中使用的iter和路径是否有效,它们是有效的,但是Python仍然每次都会抛出cookies。我的DnD foo非常差,Python更差,但我认为在该处理程序中调用drag_data_get()是不正确的。我相信您需要在
选择中设置数据。如果没有python示例,请查找gtk+教程——函数应该类似,概念应该完全相同。也许我只是在drag_data_uget()上读了API文档,但读错了,但我认为该方法的目的是设置selection对象以保存TreeDragSource中的行表示,例如我在项目中使用的ListStore。我已经检查了所有我能找到的教程,没有一个讨论如何在Gtk.TreeModel中对多列行进行DND(更准确地说,如何使用表示多列TreeModel行的数据设置选择对象)。我曾希望Gtk.TreeDragSource.drag_data_get()是解决方案,但正如前面提到的,我没有成功;谢谢你的建议!奇怪的是,尽管Gtk.TreeDragSource.drag_data_get()每次都会使Python崩溃,但Gtk.TreeDragDest.drag_data_received()的工作原理与预期一致(只要它有一个包含TreeView行数据的选择对象)。现在,如果我不使用TreeView就可以让DND工作,那么就可以设置_reorderable(True),这样我就可以完全控制何时、何地以及如何将要移回TreeView的行插入到树视图中!