[pygtk] Changing the drop icon while dragging

Radomir Dopieralski pygtk at sheep.art.pl
Thu Oct 19 21:52:46 WST 2006


Hello,

I'm new to this mailing list, and pretty new to pygtk too.
I'm writing some toy programs in order to learn it "by use".

Recently I have stumbled into a problem that I cannot solve.

I'm trying to implement mouse gestures by (ab)using gtk's drag
and drop mechanism. I have a viewport widget that I have set up
to receive drag-n-drops from itself. I'm using the drag-motion
events to determine the direction of the drag, and therefore
the action to be performed.

In order to make the interface a little more discoverable, I
want to change the drag icon depending on what action would
be performed if the user released the mouse button. I found
two sets of functions that change the drag icon:

gtk.Widget.drag_source_set_icon* 
gtk.gdk.DragContext.set_icon_*

The problem is that they work allright when called from a
drag-begin callback function, but do nothing when called
withing a drag-motion callback function.

Now, the question is, is it possible to force the icon change
while the icon is actually being dragged, or should I use a
custom mechanism to display the icon?
In the latter case, what is the best way to do it?

Here is a snippet of code that demonstrates what I'm trying to do:

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

def on_view_drag_begin(view, context):
    context.set_icon_stock(gtk.STOCK_CANCEL, 16, 16)
    # XXX Here the icon changing works fine

def on_view_drag_motion(view, context, x, y, time):
    global drag_start_x
    if drag_start_x is None:
        drag_start_x = x
    elif (drag_start_x-x>0):
        context.set_icon_stock(gtk.STOCK_GO_BACK, 16, 16)
        # XXX Here the icon changing doesn't work (icon doesn't change)
    else:
        context.set_icon_stock(gtk.STOCK_GO_FORWARD, 16, 16)
        # XXX Here the icon changing doesn't work (icon doesn't change)

def on_view_drag_end(view, context):
    global drag_start_x
    drag_start_x = None

drag_start_x = None
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.resize(400, 400)
view = gtk.Viewport()
window.add(view)
window.show_all()
drag_targets = [('gesture', gtk.TARGET_SAME_WIDGET, 0)]
view.drag_source_set(gtk.gdk.BUTTON2_MASK, drag_targets, gtk.gdk.ACTION_DEFAULT)
view.drag_dest_set(gtk.DEST_DEFAULT_MOTION, drag_targets, gtk.gdk.ACTION_DEFAULT)
view.connect('drag_motion', on_view_drag_motion)
view.connect('drag_begin', on_view_drag_begin)
view.connect('drag_end', on_view_drag_end)
gtk.main()

-- 
Radomir `The Sheep' Dopieralski

"When in doubt, use brute force." [Ken Thompson]


More information about the pygtk mailing list