arrastrar y soltar no responde en pygobject

estoy intentando que el método de arrastrar y soltar funcione bien en pygobject, pero es lento y no responde, el 90% del tiempo tengo que agitar el elemento que estoy arrastrando antes de que pueda soltarlo correctamente, ¿alguien puede ver si lo estoy haciendo incorrectamente? ¿O es esto un error con pygobject? aqui esta mi codigo

from gi.repository import Gtk, GdkPixbuf, Gdk import os def got_data_cb(windowid, context, x, y, data, info, time): # Got data. tempArray = data.get_text().splitlines() for i in tempArray: i = i.replace('file://','') print i windowid.get_model().append([i]) context.finish(True, False, time) def drop_cb(windowid, context, x, y, time): # Some data was dropped, get the data windowid.drag_get_data(context, context.list_targets()[-1], time) return True def main(): win = Gtk.Window() win.connect('destroy', lambda x: Gtk.main_quit()) win.set_default_size(450, 400) amodel = Gtk.ListStore(str) column = Gtk.TreeViewColumn() title = Gtk.CellRendererText() column.pack_start(title, True) column.add_attribute(title, "text", 0) atree = Gtk.TreeView(amodel) atree.append_column(column) builder = Gtk.Builder() filename = os.path.join('', 'treeview.ui') builder.add_from_file(filename) abox = builder.get_object('treeview1') atree.drag_dest_set(0, [], 0) atree.connect('drag_motion', lambda v,w,x,y,z: True) atree.connect('drag_drop', drop_cb) atree.connect('drag_data_received', got_data_cb) win.add(atree) win.show_all() if __name__ == '__main__': Gtk.main() main() 

Debido a que no tengo el archivo “treeview.ui”, usted hizo referencia, porté el ejemplo de vista de árbol de arrastrar y soltar de pygtk.

Este podría ser también un ejemplo sobre cómo convertir el código pygtk antiguo a pygi. Sólo pruebo este código con python3.

 #!/usr/bin/env python # example treeviewdnd.py from gi.repository import Gtk, Gdk, Pango, GObject class TreeViewDnDExample: TARGETS = [ ('MY_TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0), ('text/plain', 0, 1), ('TEXT', 0, 2), ('STRING', 0, 3), ] # close the window and quit def delete_event(self, widget, event, data=None): Gtk.main_quit() return False def clear_selected(self, button): selection = self.treeview.get_selection() model, iter = selection.get_selected() if iter: model.remove(iter) return def __init__(self): # Create a new window self.window = Gtk.Window() self.window.set_title("URL Cache") self.window.set_size_request(200, 200) self.window.connect("delete_event", self.delete_event) self.scrolledwindow = Gtk.ScrolledWindow() self.vbox = Gtk.VBox() self.hbox = Gtk.HButtonBox() self.vbox.pack_start(self.scrolledwindow, True, True, 0) self.vbox.pack_start(self.hbox, False, True, 0) self.b0 = Gtk.Button('Clear All') self.b1 = Gtk.Button('Clear Selected') self.hbox.pack_start(self.b0, True, True, 0) self.hbox.pack_start(self.b1, True, True, 0) # create a liststore with one string column to use as the model self.liststore = Gtk.ListStore(str) # create the TreeView using liststore self.treeview = Gtk.TreeView(self.liststore) # create a CellRenderer to render the data self.cell = Gtk.CellRendererText() # create the TreeViewColumns to display the data self.tvcolumn = Gtk.TreeViewColumn('URL', self.cell, text=0) # add columns to treeview self.treeview.append_column(self.tvcolumn) self.b0.connect_object('clicked', Gtk.ListStore.clear, self.liststore) self.b1.connect('clicked', self.clear_selected) # make treeview searchable self.treeview.set_search_column(0) # Allow sorting on the column self.tvcolumn.set_sort_column_id(0) # Allow enable drag and drop of rows including row move self.treeview.enable_model_drag_source( Gdk.ModifierType.BUTTON1_MASK, self.TARGETS, Gdk.DragAction.DEFAULT| Gdk.DragAction.MOVE) self.treeview.enable_model_drag_dest(self.TARGETS, Gdk.DragAction.DEFAULT) self.treeview.drag_dest_add_text_targets() self.treeview.drag_source_add_text_targets() self.treeview.connect("drag_data_get", self.drag_data_get_data) self.treeview.connect("drag_data_received", self.drag_data_received_data) self.scrolledwindow.add(self.treeview) self.window.add(self.vbox) self.window.show_all() def drag_data_get_data(self, treeview, context, selection, target_id, etime): treeselection = treeview.get_selection() model, iter = treeselection.get_selected() data = bytes(model.get_value(iter, 0), "utf-8") selection.set(selection.get_target(), 8, data) def drag_data_received_data(self, treeview, context, x, y, selection, info, etime): model = treeview.get_model() data = selection.get_data().decode("utf-8") 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.TreeViewDropPosition.BEFORE or position == Gtk.TreeViewDropPosition.BEFORE): model.insert_before(iter, [data]) else: model.insert_after(iter, [data]) else: model.append([data]) if context.get_actions() == Gdk.DragAction.MOVE: context.finish(True, True, etime) return def main(): Gtk.main() if __name__ == "__main__": treeviewdndex = TreeViewDnDExample() main() 

Para poder obtener un funcionamiento de arrastrar y soltar desde otra aplicación de escritorio a mi aplicación, tuve que agregar un drag_motion_callback para copiar los datos al contexto:

 Class Window(Gtk.Window): def __init__(self): #other stuff before here #Set up dragNdrop to add URIs to open draw self.connect("drag-motion", self.motion_cb) self.connect("drag-drop", self.drop_cb) self.connect("drag-data-received", self.got_data_cb) self.drag_dest_set(0, [], 0) def motion_cb(self, wid, context, x, y, time): Gdk.drag_status(context,Gdk.DragAction.COPY, time) # Returning True which means "I accept this data". return True def drop_cb(self, wid, context, x, y, time): wid.drag_get_data(context, context.list_targets()[-1], time) def got_data_cb(self, wid, context, x, y, data, info, time): #Need to do something here files=data.get_text().rstrip('\n').split('\n') for fn in files: fn= fn.split('file://',1)[-1] self.add_file(fn) self.place_items() print files context.finish(True, False, time)