I have searched for examples, but all the examples were the opposite direction (my app is getting file drag-and-drop from another application). But this must be possible because I can drag a file from Files (Nautilus) to another app, Text Editor (gedit).
Could you show me a very simple example of a GTK Window with one widget on it, and when I drag from the widget to Text Editor, it passes a text file on the system (such as /home/user/.profile
) to the Text Editor so that it will open the text file?
In order to make it so that your application can receive files, you need to use uri
. In the function you bind to drag-data-received
, you can use data.get_uris()
to get a list of the files that were dropped. Make sure that you call drag_dest_add_uri_targets()
, so that the widget can receive URIs.
This code example has one button that drags a file, and another button that can receive it. You can also drag the file and drop it into any file-receiving app, such as gedit (Text Editor) or VSCode.
import gi
gi.require_version("Gdk", "3.0")
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
window = Gtk.Window()
window.connect("delete-event", Gtk.main_quit)
box = Gtk.HBox()
window.add(box)
# Called when the Drag button is dragged on
def on_drag_data_get(widget, drag_context, data, info, time):
data.set_uris(["file:///home/user/test.html"])
# Called when the Drop button is dropped on
def on_drag_data_received(widget, drag_context, x, y, data, info, time):
print("Received uris: %s" % data.get_uris())
# The button from which the file is dragged
drag_button = Gtk.Button(label="Drag")
drag_button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.LINK)
drag_button.drag_source_add_uri_targets() # This makes sure that the buttons are using URIs, not text
drag_button.connect("drag-data-get", on_drag_data_get)
box.add(drag_button)
# The button into which the file can be dropped
drop_button = Gtk.Button(label="Drop")
drop_button.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.LINK)
drop_button.drag_dest_add_uri_targets() # This makes sure that the buttons are using URIs, not text
drop_button.connect("drag-data-received", on_drag_data_received)
box.add(drop_button)
window.show_all()
Gtk.main()