"I have a simple mission: To create an open-source, non-linear video editor for Linux. Many have tried and fallen before me, but for some reason I feel compelled to try myself. I am documenting my journey in this blog for all to read. It will be a dangerous journey, and I might not make it back alive. Hold on tight, and enjoy the ride! By the way, I'm calling this project OpenShot Video Editor!"

Have you ever wanted to change the drag icon on a GTK TreeView control using Python? This sounds really easy, but in fact there is a trick to getting it to work correctly. Hopefully you have found this blog prior to spending 7 days searching for a solution (like I did).

I have posted a fully working example program below, that will demonstrate how to successfully change the icon used during a drag operation. Pay close attention to way the drag_begin signal is connected (hint: that's the trick). Also, for this example to work, you must change the image path to point at a valid JPG or PNG image on your computer.

Hopefully the world is a better place now that I've shared this example. Good luck!

# import the gtk library
import gtk

# signal handler for the tree drag begin signal
# change the drag icon to a JPG as soon as the drag starts
# *** BE SURE TO CONNECT THIS EVENT WITH THE "CONNECT_AFTER(" SYNTAX ***
# *** THE ICON WILL NOT CHANGE UNLESS THIS METHOD IS USED TO CONNECT ***
def on_drag_begin(widget, context):
print "Drag Begin"

# Get a pixbuf of an image (i.e. JPG). This will be your icon.
play_image = gtk.image_new_from_file("glade/icons/jpg/arrow.jpg")
mypixbuf = play_image.get_pixbuf()

# Change the icon to the pixbuf (i.e. the JPG)
context.set_icon_pixbuf(mypixbuf, 10, 10)

# add tree to window
myTree = gtk.TreeView()

# Enable drag and drop on the treeview. If you don't call this method,
# the tree won't allow you to drag anything
myTree.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [('text/plain', 0, 0)], gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE)

# connect the drag begin signal handler. Be sure
# to use the "connect_after" syntax and not the regular "connect".
myTree.connect_after('drag_begin', on_drag_begin)

# create a TreeStore with one string column to use as the model
myTreeStore = gtk.TreeStore(str, str)

# we'll add some data now
myTreeStore.append(None, ["Choose a Video or Audio File to Begin", ""])

# Set the treeview's data model
myTree.set_model(myTreeStore)

# create 2 TreeViewColumns to display the data
tvcolumn = gtk.TreeViewColumn('File Name')
tvcolumn1 = gtk.TreeViewColumn('Length')

# add columns to treeview
myTree.append_column(tvcolumn)
myTree.append_column(tvcolumn1)

# create a CellRendererText to render the data
cell = gtk.CellRendererText()
cell1 = gtk.CellRendererText()

# add the cell to the tvcolumn and allow it to expand
tvcolumn.pack_start(cell, True)
tvcolumn1.pack_start(cell1, True)

# set the cell "text" attribute to column 0 - retrieve text
# from that column in treestore
tvcolumn.add_attribute(cell, 'text', 0)
tvcolumn1.add_attribute(cell1, 'text', 1)

# create new window and add the treeview
window = gtk.Window()
window.add(myTree)
window.show_all()

# Start the Main loop
gtk.main()

2 comments

  1. malacusp  

    Thanks very much for this it saved me ages of searching for a quick fix for my menu app. USP
    http://code.google.com/p/ubuntu-system-panel/

    I'll put a credit in for you.

  2. Jonathan Thomas  

    No problem! I'm glad this code snippet helped you out.

Post a Comment

Subscribe to: Post Comments (Atom)