GTK3 – Drag and Drop

6
Seguendo il tutorial di Sebastian Pölsterl si trova subito un warning minaccioso:

Note
Versions of PyGObject < 3.0.3 contain a bug which does not allow drag and drop to function correctly. Therefore a version of PyGObject >= 3.0.3 is required for the following examples to work.

Panico ❓ Meglio verificare:
version
OK, niente panico, come scritto anche sulla copertina della Guida Galattica, si procede 😀

Per abilitare il drag & drop (trascina e scarica?) tra i vari widget si usano i metodi Gtk.Widget.drag_source_set()Gtk.Widget.drag_dest_set(). A volte ne sono richiesti altri quali Gtk.TreeView e Gtk.IconView.

Il tutorial menzionato sopra è qui un po’ troppo filosofico, per me. In fondo mi basta poco, che si vede chiaramente dall’esempio. In ogni caso eco i metodi.

Metodi e oggetti per il D&D

class Gtk.Widget

drag_source_set(start_button_mask, targets, actions)
definisce il widget sorgente del drag.

drag_dest_set(flags, targets, actions)
destinazione del drop.

drag_source_add_text_targets()
drag_dest_add_text_targets()
per il testo.

drag_source_add_image_targets()
drag_dest_add_image_targets()
per le immagini.

drag_source_add_uri_targets()
drag_dest_add_uri_targets()
per quando ci sono di mezzo URI.

class Gtk.TargetEntry

static new(target, flags, info)
crea un nuovo target. target  è una stringa che descrive il tipo di dati. flags controlla le condizioni del trasferimento, è una combinazione di Gtk.TargetFlags.SAME_APP, Gtk.TargetFlags.SAME_WIDGET, Gtk.TargetFlags.OTHER_APP e Gtk.TargetFlags.OTHER_WIDGET. info è l’ID dell’applicazione.

class Gtk.SelectionData

get_text()
ritorna il testo della selezione.

set_text(text)
setta text, testo della selezione.

get_pixbuf()
ritorna il pixbuf (immagine) della selezione.

set_pixbuf(pixbuf)
setta pixbuf, dati della selezione.

Segnali sorgente drag

dss

dssSegnali destinazione drag

dds

L’esempio riportato nel tutorial dev’essere corretto eliminando le linee che ho lasciato commentate (52 e 53).

#!/usr/bin/python3

# dd.py

from gi.repository import Gtk, Gdk, GdkPixbuf

(TARGET_ENTRY_TEXT, TARGET_ENTRY_PIXBUF) = range(2)
(COLUMN_TEXT, COLUMN_PIXBUF) = range(2)

DRAG_ACTION = Gdk.DragAction.COPY

class DragDropWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Drag and Drop Demo")

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(vbox)

        hbox = Gtk.Box(spacing=12)
        vbox.pack_start(hbox, True, True, 0)

        self.iconview = DragSourceIconView()
        self.drop_area = DropArea()

        hbox.pack_start(self.iconview, True, True, 0)
        hbox.pack_start(self.drop_area, True, True, 0)

        button_box = Gtk.Box(spacing=6)
        vbox.pack_start(button_box, True, False, 0)

        image_button = Gtk.RadioButton.new_with_label_from_widget(None,
            "Images")
        image_button.connect("toggled", self.add_image_targets)
        button_box.pack_start(image_button, True, False, 0)

        text_button = Gtk.RadioButton.new_with_label_from_widget(image_button,
            "Text")
        text_button.connect("toggled", self.add_text_targets)
        button_box.pack_start(text_button, True, False, 0)

        self.add_image_targets()

    def add_image_targets(self, button=None):
        targets = Gtk.TargetList.new([])
        targets.add_image_targets(TARGET_ENTRY_PIXBUF, True)

        self.drop_area.drag_dest_set_target_list(targets)
        self.iconview.drag_source_set_target_list(targets)

    def add_text_targets(self, button=None):
        #self.drop_area.drag_dest_set_target_list(None)
        #self.iconview.drag_source_set_target_list(None)

        self.drop_area.drag_dest_add_text_targets()
        self.iconview.drag_source_add_text_targets()

class DragSourceIconView(Gtk.IconView):

    def __init__(self):
        Gtk.IconView.__init__(self)
        self.set_text_column(COLUMN_TEXT)
        self.set_pixbuf_column(COLUMN_PIXBUF)

        model = Gtk.ListStore(str, GdkPixbuf.Pixbuf)
        self.set_model(model)
        self.add_item("Item 1", "image")
        self.add_item("Item 2", "gtk-about")
        self.add_item("Item 3", "edit-copy")

        self.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [],
            DRAG_ACTION)
        self.connect("drag-data-get", self.on_drag_data_get)

    def on_drag_data_get(self, widget, drag_context, data, info, time):
        selected_path = self.get_selected_items()[0]
        selected_iter = self.get_model().get_iter(selected_path)

        if info == TARGET_ENTRY_TEXT:
            text = self.get_model().get_value(selected_iter, COLUMN_TEXT)
            data.set_text(text, -1)
        elif info == TARGET_ENTRY_PIXBUF:
            pixbuf = self.get_model().get_value(selected_iter, COLUMN_PIXBUF)
            data.set_pixbuf(pixbuf)

    def add_item(self, text, icon_name):
        pixbuf = Gtk.IconTheme.get_default().load_icon(icon_name, 16, 0)
        self.get_model().append([text, pixbuf])

class DropArea(Gtk.Label):

    def __init__(self):
        Gtk.Label.__init__(self, "Drop something on me!")
        self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION)

        self.connect("drag-data-received", self.on_drag_data_received)

    def on_drag_data_received(self, widget, drag_context, x,y, data,info, time):
        if info == TARGET_ENTRY_TEXT:
            text = data.get_text()
            m = "Received text: %s" % text
            print(m)

        elif info == TARGET_ENTRY_PIXBUF:
            pixbuf = data.get_pixbuf()
            width = pixbuf.get_width()
            height = pixbuf.get_height()

            m = "Received pixbuf with width %spx and height %spx" % (width,
                height)
            print(m)

win = DragDropWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

dd

Advertisements
Post a comment or leave a trackback: Trackback URL.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: