Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mi4code/d53b81ed6353275e9bbeedfb7b5fd990 to your computer and use it in GitHub Desktop.
Save mi4code/d53b81ed6353275e9bbeedfb7b5fd990 to your computer and use it in GitHub Desktop.
How to drag and drop files in GTK4 and GTK3 in python

How to drag and drop files in GTK4 and GTK3

Here is how to achieve drag and drop functionality in GTK in python. Recently I needed this for my project and it took me some time to find how to do that, so now I'm sharing it in case anyone needs it.

GTK4

Drag source implementation:

button = Gtk.Button(label="Drag File")
drag = Gtk.DragSource.new()
drag.set_actions(Gdk.DragAction.COPY)

def on_drag(drag_source, x, y):
    file_list = ["/path/to/your/file1","/path/to/your/file2"]
    data = Gdk.FileList.new_from_list([Gio.File.new_for_path(i) for i in file_list])
    print("Draged file(s):", [i.get_path() for i in data.get_files()])
    content = Gdk.ContentProvider.new_for_value(data)
    return content

drag.connect('prepare', on_drag)
drag.connect('drag-begin', lambda drag_source,data: print('drag begin') )
drag.connect('drag-end', lambda drag,drag_data,flag: print('drag end'))
button.add_controller(drag)

container.append(button)

Drop target implementation:

label = Gtk.Label(label="Drop File Here")
drop = Gtk.DropTarget.new(Gdk.FileList, Gdk.DragAction.COPY)

def on_drop(value, user_data, x, y):
    print("Dropped file(s):", [i.get_path() for i in user_data.get_files()])

drop.connect('drop', on_drop)
drop.connect('accept', lambda drop,user_data: True)
drop.connect('enter', lambda drop_target,x,y: Gdk.DragAction.COPY)
drop.connect('motion', lambda drop_target,x,y: Gdk.DragAction.COPY)
drop.connect('leave', lambda user_data: None)
label.add_controller(drop)

container.append(label)

GTK3

Drag source implementation:

button = Gtk.Button(label="Drag File")
button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags.SAME_WIDGET, 0)], Gdk.DragAction.COPY)

def on_drag(widget, context, data, info, time):
    file_list = ["/path/to/your/file1","/path/to/your/file2"]
    uris = [("file://" + i.replace(" ","%20")) for i in file_list]
    print("Draged file(s):", uris)
    data.set_uris(uris)

button.connect("drag-data-get", on_drag)

container.add(button)

Drop target implementation:

label = Gtk.Label(label="Drop File Here")
label.drag_dest_set(Gtk.DestDefaults.ALL, [Gtk.TargetEntry.new("text/uri-list", 0, 0)], Gdk.DragAction.COPY)
   
def on_drop(widget, context, x, y, data, info, time):
    uris = data.get_uris()
    print("Dropped file(s):", uris)

label.connect("drag-data-received", on_drop)
container.add(label)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment