#!/usr/bin/env python import pygtk import gtk class custom(gtk.EventBox): def __init__(self): gtk.EventBox.__init__(self) self.fixed = gtk.Fixed() self.add(self.fixed) # connect to the motion notify event self.connect("motion-notify-event", self.move) self.set_events(gtk.gdk.ALL_EVENTS_MASK) # create a child object (an event box wrapped around an icon) cw = gtk.EventBox() ci = gtk.Image() ci.set_from_stock(gtk.STOCK_FILE, gtk.ICON_SIZE_DND) cw.add(ci) self.fixed.put(cw, 50, 50) #connect to the object's button events cw.connect("button-press-event", self.childpress) cw.connect("button-release-event", self.childrelease) # state variables self.moving = False self.moving_widget = None def move(self, widget, event): # if we're in moving state, set the widget's position to the # current mouse coordinates. # the problem here is that we seem to get two mouse coordinates # from the parent window that alternate between two different coordinate # spaces, causing the object to rapidly flash between two locations. if self.moving and self.moving_widget: assert event.window != self.window self.fixed.move(self.moving_widget, int(event.x) + self.moving_widget.allocation.x - self.delta[0], int(event.y) + self.moving_widget.allocation.y - self.delta[1]) return True def childpress(self, widget, event): # set the state to moving, and set the moving target self.moving = True self.moving_widget = widget self.delta = (int(event.x), int(event.y)) def childrelease(self, widget, event): # set the state to not moving self.moving = False self.moving_widget = None window = gtk.Window() window.set_size_request(300,200) evbox = custom() window.add(evbox) window.show_all() gtk.main()