Привет. Поздравляю. :)
А вот вариант решения на PyGTK. По-моему проще. Ухваченная картинка ложится всегда сверху ( по идее, так и должно быть). Движение на второй картинке(av3435.gif - движущийся пингвин в моем профиле) сохраняется.
#!/usr/bin/python
# coding: utf-8
import pygtk
from gtk import *
import time
class DNDImageButton:
file1 ="/home/mike/Desktop/lena.jpg"
file2 ="/home/mike/Desktop/av3435.gif"
fromImage=[("",0,0),("",0,0)]
toCanvas=[("",0,0)]
def __init__(self):
################### хэши - для распознавания кнопок ############################
global HASH,HASH1,HASH2
self.window = Window(WINDOW_TOPLEVEL)
self.window.set_default_size(500, 500)
self.window.connect("destroy", lambda w: main_quit())
self.window.show()
layout = self.makeLayout()
self.window.add(layout)
self.myaddImage(100, 100, self.file1)
self.myaddImage(200, 200, self.file2)
################### установки layout-a ###########################
def layout_resize(self, widget, event):
x, y, width, height = widget.get_allocation()
if width > self.lwidth or height > self.lheight:
self.lwidth = max(width, self.lwidth)
self.lheight = max(height, self.lheight)
widget.set_size(self.lwidth, self.lheight)
def makeLayout(self):
self.lwidth = 0
self.lheight = 0
box = VBox()
box.show()
table = Table()
table.show()
box.pack_start(table)
layout = Layout()
self.layout = layout
layout.set_size(self.lwidth, self.lheight)
layout.connect("size-allocate", self.layout_resize)
layout.show()
table.attach(layout, 0, 1, 0, 1, FILL|EXPAND, FILL|EXPAND, 0, 0)
################### испускаем сигналы при перетаскивании ##########################
layout.connect('drag_leave', self.target_drag_leave)
layout.connect('drag_motion', self.target_drag_motion)
layout.connect('drag_drop', self.target_drag_drop)
layout.connect("drag_data_received", self.receiveCallback)
################### установки цели ##########################
layout.drag_dest_set(DEST_DEFAULT_MOTION |
DEST_DEFAULT_HIGHLIGHT |
DEST_DEFAULT_DROP,
self.toCanvas, gdk.ACTION_MOVE )
return box
####################### устаеавл. виджет в коорд. xd, yd ##########################
def myaddImage(self, xd, yd, f):
global HASH,HASH1,HASH2
hadj = self.layout.get_hadjustment()
vadj = self.layout.get_vadjustment()
image = Image()
image.set_from_file(f)
button = Button()
button.add(image)
if f == self.file1:
HASH1 = button.__hash__()
else:
HASH2 = button.__hash__()
####################### соединяем виджет ##########################
button.connect('button_press_event', self.button_press)
button.connect("drag_data_get", self.sendCallback)
button.connect('drag_data_delete', self.delete_cb)
button.connect("drag_data_received", self.receiveCallback)
###################### установки источника ##########################
button.drag_source_set(gdk.BUTTON1_MASK, self.fromImage, gdk.ACTION_MOVE )
button.show_all()
self.layout.put(button, int(xd+hadj.value), int(yd+vadj.value))
print 'create button'
return
####################### функции CALLBACK ##########################
def button_press(self,button,event):
global HASH,HASH1,HASH2
print 'button_press'
HASH = button.__hash__()
def sendCallback(self, widget, context, selection, targetType, eventTime):
print "send_cb "
selection.set(selection.target, 8, "")
def receiveCallback(self, widget, context, x, y, selection, targetType, time):
global HASH,HASH1,HASH2
print "receive_cb "
if HASH == HASH1:
self.myaddImage(x,y,self.file1)
else:
self.myaddImage(x,y,self.file2)
def delete_cb(self, widget, context):
print "delete_cb "
widget.hide_on_delete()
def target_drag_leave(self, widget, context, time):
print 'leave'
def target_drag_motion(self, widget, context, x, y, time):
print 'motion'
print x,y
def target_drag_drop(self, widget, context, x, y, time):
print 'drop'
####################################################################
####################################################################
DNDImageButton()
main()