8 Oct

Once again I find myself struggling with Drag 'n Drop using GTK and Python. Why is it so difficult to get something working? Why do all the examples on the Internet suck? These are all good questions my friends, and today I bring some answers.

First of all, there are many different levels of drag 'n drop in GTK. There are some higher level methods and some lower level methods. I won't pretend to be an expert, but instead I will share a SUPER USEFUL example I've found and modified. If you are struggling to implement drag 'n drop in your application, please stop now, and run this example. Hopefully, this will work with your own widgets and save you some time.

import pygtk
pygtk.require('2.0')
import gtk

# function to track the motion of the cursor while dragging
def motion_cb(wid, context, x, y, time):
print "motion"
context.drag_status(gtk.gdk.ACTION_COPY, time)
return True

# function to print out the mime type of the drop item
def drop_cb(wid, context, x, y, time):
l.set_text('\n'.join([str(t) for t in context.targets]))
context.finish(True, False, time)
return True

# Create a GTK window and Label, and hook up
# drag n drop signal handlers to the window
w = gtk.Window()
w.set_size_request(200, 150)
w.drag_dest_set(0, [], 0)
w.connect('drag_motion', motion_cb)
w.connect('drag_drop', drop_cb)
w.connect('destroy', lambda w: gtk.main_quit())
l = gtk.Label()
w.add(l)
w.show_all()

# Start the program
gtk.main()

My previous posts about drag n' drop used some of the higher level methods and signals, such as drag_data_received. This worked great for dropping text/uri-list type items on a gtkTreeView, but it didn't work for tree nodes (which are type GTK_TREE_MODEL_ROW). In other words, it didn't work with a tree node as a drop item... instead it seemed to ignore that type of item.

So, to wrap this up, use the above example in your program, cross your fingers, and I hope this might save you some time. Good luck!