Пример Drag and Drop на GTK 3
Автор: Igor Kirsanov
Пример из официальной документации по GTK and python 3
import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk, GdkPixbuf (TARGET_ENTRY_TEXT, TARGET_ENTRY_PIXBUF) = range(2) (COLUMN_TEXT, COLUMN_PIXBUF) = range(2) DRAG_ACTION = Gdk.DragAction.COPY class DragDropWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="Drag and Drop Demo") vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.add(vbox) hbox = Gtk.Box(spacing=12) vbox.pack_start(hbox, True, True, 0) self.iconview = DragSourceIconView() self.drop_area = DropArea() hbox.pack_start(self.iconview, True, True, 0) hbox.pack_start(self.drop_area, True, True, 0) button_box = Gtk.Box(spacing=6) vbox.pack_start(button_box, True, False, 0) image_button = Gtk.RadioButton.new_with_label_from_widget(None, "Images") image_button.connect("toggled", self.add_image_targets) button_box.pack_start(image_button, True, False, 0) text_button = Gtk.RadioButton.new_with_label_from_widget(image_button, "Text") text_button.connect("toggled", self.add_text_targets) button_box.pack_start(text_button, True, False, 0) self.add_image_targets() def add_image_targets(self, button=None): targets = Gtk.TargetList.new([]) targets.add_image_targets(TARGET_ENTRY_PIXBUF, True) self.drop_area.drag_dest_set_target_list(targets) self.iconview.drag_source_set_target_list(targets) def add_text_targets(self, button=None): self.drop_area.drag_dest_set_target_list(None) self.iconview.drag_source_set_target_list(None) self.drop_area.drag_dest_add_text_targets() self.iconview.drag_source_add_text_targets() class DragSourceIconView(Gtk.IconView): def __init__(self): Gtk.IconView.__init__(self) self.set_text_column(COLUMN_TEXT) self.set_pixbuf_column(COLUMN_PIXBUF) model = Gtk.ListStore(str, GdkPixbuf.Pixbuf) self.set_model(model) self.add_item("Item 1", "image-missing") self.add_item("Item 2", "help-about") self.add_item("Item 3", "edit-copy") self.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [], DRAG_ACTION) self.connect("drag-data-get", self.on_drag_data_get) def on_drag_data_get(self, widget, drag_context, data, info, time): selected_path = self.get_selected_items()[0] selected_iter = self.get_model().get_iter(selected_path) if info == TARGET_ENTRY_TEXT: text = self.get_model().get_value(selected_iter, COLUMN_TEXT) data.set_text(text, -1) elif info == TARGET_ENTRY_PIXBUF: pixbuf = self.get_model().get_value(selected_iter, COLUMN_PIXBUF) data.set_pixbuf(pixbuf) def add_item(self, text, icon_name): pixbuf = Gtk.IconTheme.get_default().load_icon(icon_name, 16, 0) self.get_model().append([text, pixbuf]) class DropArea(Gtk.Label): def __init__(self): Gtk.Label.__init__(self, "Drop something on me!") self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION) self.connect("drag-data-received", self.on_drag_data_received) def on_drag_data_received(self, widget, drag_context, x, y, data, info, time): if info == TARGET_ENTRY_TEXT: text = data.get_text() print("Received text: %s" % text) elif info == TARGET_ENTRY_PIXBUF: pixbuf = data.get_pixbuf() width = pixbuf.get_width() height = pixbuf.get_height() print("Received pixbuf with width %spx and height %spx" % (width, height)) win = DragDropWindow() win.connect("delete-event", Gtk.main_quit) win.show_all() Gtk.main()