Apro un nuovo topic perché di fatto l'argomento della discussione è diverso da quello della precedente.
Ho la mia finestra con diversi VBox ognuno dei quali contiene una sfilza di gtk.Buttons:



Quello che vorrei realizzare è il drag&drop tra i diversi VBox, in modo da poter inserire un button in mezzo a due buttons di un'altra fila.

Ho notato che riguardo al drag&drop in pygtk non è che la documentazione sia molto puntuale, per cui ho realizzato qualcosa semplicemente prendendo ispirazione dai codici di esempio che si trovano in rete.

Ho pensato che il codice del D&D andrà sui pulsanti, dato che sarà uno di essi ad essere draggato e su uno di essi avverrà il drop. Ecco il codice che ho inserito:

[hlpycode]   
def __init__(self, tempo_infornata, spacer):
        gtk.Button.__init__(self)
        self.set_size_request(tempo_infornata,50)
        r = random.randrange(0, 65535 + 1)
        g = random.randrange(0, 65535 + 1)
        b = random.randrange(0, 65535 + 1)
        map   = self.get_colormap()
        color_off = map.alloc_color(gtk.gdk.Color(r,g,b))
        style = self.get_style().copy()
        self.set_style(style)
        style.bg[gtk.STATE_NORMAL] = gtk.gdk.Color(r,g,b)

        #Drag and drop data
        self.drag_dest_set(0, [], 0)
        self.drag_source_set(0, [], 0)
        self.connect('drag-leave', self.leave_cb)
        self.connect('drag-drop', self.drop_cb)
        self.connect('drag-motion', self.motion_cb)
        self.connect('drag-data-get', self.data_cb)
        self.connect('drag-begin', self.begin_cb)
        self.drag_source_set(gtk.gdk.BUTTON1_MASK, self.fromButton,
                               gtk.gdk.ACTION_COPY)
        self.connect("drag-data-received", self.receiveCallback)
        self.drag_dest_set(gtk.DEST_DEFAULT_MOTION |
                            gtk.DEST_DEFAULT_HIGHLIGHT |
                            gtk.DEST_DEFAULT_DROP,
                            self.toButton,
                            gtk.gdk.ACTION_COPY)

        #self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(r,g,b))
        self.length = tempo_infornata
   
    def motion_cb(self, wid, context, x, y, time):
        context.drag_status(gtk.gdk.ACTION_COPY, time)
        #Qui si arriva ogni volta che si passa con il pulsante draggato sopra ad un altro
        print "Sei in motion_cb. Significa che stai passando col pulsante draggato sopra ad un altro, cioe' %s" % self

    def leave_cb(self, widget, context, info):
        #Qui si arriva ogni volta che da un pulsante draggando si passa ad un altro
        print "Sei in leave_cb. Hai lasciato il clic del mouse sull'oggetto %s" % self
        pass

    def received_cb(self, wid, context, x, y, time):
        print "Sei in received_cb"

    def data_cb(self, wid, context, data, x, y):
        print "Sei in data_cb. Sarebbe forse il momento giusto per gestire l'inserimento?"
        print "" .join([str(t) for t in context.targets])
        print data.get_text()
        print data

    def drop_cb(self, wid, context, x, y, time):
        print "E' il momento del drop, sei in drop_cb"
        if context.targets:
            print "context.targets non e' vuoto. Ecco cosa incolli -->"
#            wid.data_cb(context, context.targets[0], time)
            print "" .join([str(t) for t in context.targets])
        #print "%s drop" % self.stampa()

    def begin_cb(self, x, y):
        print "Inizia il Drag and Drop. begin_cb"

    def drag_data_received(self, img, context, x, y, data, info, time):
        #if data.format == 80:
            print "Received %s " % data.data

    def receiveCallback(self, widget, context, x, y, selection, targetType,time):
        print "receiveCallback"
        if targetType == self.TARGET_TYPE_TEXT:
            print   selection.data
            self.inserisci_infornata(string.split(selection.data, '\n'), x, y)

    def send_callback(self):
        print "Send_Callback"

    def inserisci_infornata(self, data, xd, yd):
        print "Sei in inserisci_infornata %s" % data[/hlpycode]

Con questo codice se provo a fare il D&D di un pulsante su un altro ottengo, come output di console:

Inizia il Drag and Drop. begin_cb
Sei in motion_cb. Significa che stai passando col pulsante draggato sopra ad un altro, cioe' <Infornata object at 0x14a5490 (GtkButton at 0xf978a0)>
Sei in motion_cb. Significa che stai passando col pulsante draggato sopra ad un altro, cioe' <Infornata object at 0x14a5490 (GtkButton at 0xf978a0)>
Sei in motion_cb. Significa che stai passando col pulsante draggato sopra ad un altro, cioe' <Infornata object at 0x14a5490 (GtkButton at 0xf978a0)>
Sei in motion_cb. Significa che stai passando col pulsante draggato sopra ad un altro, cioe' <Infornata object at 0x14a5490 (GtkButton at 0xf978a0)>
Sei in motion_cb. Significa che stai passando col pulsante draggato sopra ad un altro, cioe' <Infornata object at 0x14a5490 (GtkButton at 0xf978a0)>
Sei in motion_cb. Significa che stai passando col pulsante draggato sopra ad un altro, cioe' <Infornata object at 0x14a5490 (GtkButton at 0xf978a0)>
Sei in leave_cb. Si arriva qui ogni volta che con il pulsante draggato passi da un bottone a un altro <Infornata object at 0x14a5490 (GtkButton at 0xf978a0)>
Sei in data_cb. Sarebbe forse il momento giusto per gestire l'inserimento?
text/plain
None
<GtkSelectionData at 0x21f530>
E' il momento del drop, sei in drop_cb
context.targets non e' vuoto. Ecco cosa incolli -->
text/plain


Mi sembra di essere quindi sulla strada corretta, ma mi chiedo: ora che so che ho un text/plain che viene passato da un button all'altro, come faccio al momento del drop a estrarre da questo text/plain un riferimento al button di partenza?
Negli esempi che ho trovato in rete si parla sempre di drag/drop di file, quindi il text/plain si riferisce al percorso del file. Ma nel mio caso, in cui è un bottone, a cosa si riferisce?
Nella function drop_cb ho notato che sia self che wid (argomento passato alla funzione) si riferiscono all'oggetto sul quale si fa il drop. Come faccio a riferirmi all'oggetto che viene draggato?

Grazie in anticipo per ogni aiuto, anche link a guide sul drag&drop in pygtk sono graditi  ;)