Skip to content
Browse files

Added section describing drag and drop

  • Loading branch information...
1 parent 44af88d commit 8b1b9e0918d4f868de84be77bd0661d50c9b5a44 @and471 and471 committed with sebp Nov 28, 2011
View
89 examples/drag_and_drop_example.py
@@ -0,0 +1,89 @@
+from gi.repository import Gtk, Gdk, GdkPixbuf
+
+(TARGET_ENTRY_TEXT, TARGET_ENTRY_PIXBUF) = range(2)
+(COLUMN_TEXT, COLUMN_PIXBUF) = range(2)
+
+TARGETS = [Gtk.TargetEntry.new(
+ target = "STRING",
+ flags = Gtk.TargetFlags.SAME_APP,
+ info = TARGET_ENTRY_TEXT
+ ),
+ Gtk.TargetEntry.new(
+ target = "BITMAP",
+ flags = Gtk.TargetFlags.SAME_APP,
+ info = TARGET_ENTRY_PIXBUF
+ )]
+
+DRAG_ACTION = Gdk.DragAction.COPY
+
+
+class DragDropWindow(Gtk.Window):
+
+ def __init__(self):
+ Gtk.Window.__init__(self, title="Drag and Drop Demo")
+
+ hbox = Gtk.Box(Gtk.Orientation.HORIZONTAL, 12)
+ iconview = DragSourceIconView()
+ drop_area = DropArea()
+
+ hbox.pack_start(iconview, True, True, 0)
+ hbox.pack_start(drop_area, True, True, 0)
+
+ self.add(hbox)
+
+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, TARGETS, 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)
+ 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.DROP, TARGETS, 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()
+ print "Received text: %s" % text
+
+ elif info == TARGET_ENTRY_PIXBUF:
+ pixbuf = data.get_pixbuf()
+ width = pixbuf.get_width()
+ height = pixbuf.get_height()
+
+ print "Received pixbuf with width %spx and height %spx" % (width, height)
+
+win = DragDropWindow()
+win.connect("delete-event", Gtk.main_quit)
+win.show_all()
+Gtk.main()
View
BIN images/drag_and_drop_example.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
169 source/drag_and_drop.txt
@@ -0,0 +1,169 @@
+Drag and Drop
+=============
+.. 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.
+
+Setting up drag and drop between widgets consists of selecting a drag source
+(the widget which the user starts the drag from) with the
+:meth:`Gtk.Widget.drag_source_set` method, selecting a drag destination (the
+widget which the user drops onto) with the :meth:`Gtk.Widget.drag_dest_set`
+method and then handling the relevant signals on both widgets.
+
+Instead of using :meth:`Gtk.Widget.drag_source_set` and
+:meth:`Gtk.Widget.drag_dest_set` some specialised widgets require the use of
+specific functions (such as :class:`Gtk.TreeView` and :class:`Gtk.IconView`).
+
+A basic drag and drop only requires the source to connect to the "drag-data-get"
+signal and the destination to connect to the "drag-data-received" signal. More
+complex things such as specific drop areas and custom drag icons will require
+you to connect to :ref:`additional signals <drag-signals>` and interact with
+the :class:`Gdk.DragContext` object it supplies.
+
+In order to transfer data between the source and destination, you must interact
+with the :class:`Gtk.SelectionData` variable supplied in the
+:ref:`"drag-data-get" <drag-signals>` and :ref:`"drag-data-received" <drag-signals>`
+signals using the :class:`Gtk.SelectionData` get and set methods.
+
+Target Entries
+--------------
+To allow the drag source and destination to know what data they are receiving and
+sending, a common list of :class:`Gtk.TargetEntry's <Gtk.TargetEntry>` are required.
+A :class:`Gtk.TargetEntry` describes a piece of data that will be sent by the drag
+source and received by the drag destination.
+
+There are two ways of adding :class:`Gtk.TargetEntry's <Gtk.TargetEntry>` to a
+source and destination. If the drag and drop is simple and each target entry is
+of a different type, you can use the group of methods :meth:`mentioned here
+<Gtk.Widget.drag_source_add_text_targets>`.
+
+If you require more than one type of data or wish to do more complex things with
+the data, you will need to create the :class:`Gtk.TargetEntry's <Gtk.TargetEntry>`
+using the :meth:`Gtk.TargetEntry.new` method.
+
+Drag and Drop Methods and Objects
+---------------------------------
+.. class:: Gtk.Widget
+
+ .. method:: drag_source_set(start_button_mask, targets, actions)
+
+ Sets the widget to be a drag source.
+
+ *start_button_mask* are a combination of :attr:`Gdk.ModifierType` masks which
+ sets which buttons must be pressed for a drag to occur.
+ *targets* is a list of :class:`Gtk.TargetEntry's <Gtk.TargetEntry>` which
+ describe the data to be passed between source and destination.
+ *actions* are a combination :attr:`Gdk.DragAction` masks to show possible
+ drag actions.
+
+ .. method:: drag_dest_set(flags, targets, actions)
+
+ Sets the widget to be a drag destination.
+
+ *flags* are a combination of :attr:`Gdk.DestDefaults` masks which configures
+ the processes which occur on a drag site.
+ *targets* is a list of :class:`Gtk.TargetEntry's <Gtk.TargetEntry>` which
+ describe the data to be passed between source and destination.
+ *actions* are a combination :attr:`Gdk.DragAction` masks to show possible
+ drag actions.
+
+ .. method:: drag_source_add_text_targets()
+ drag_dest_add_text_targets()
+
+ Add a :class:`Gtk.TargetEntry` to the drag source/destination which contains
+ a piece of text.
+
+ .. method:: drag_source_add_image_targets()
+ drag_dest_add_image_targets()
+
+ Add a :class:`Gtk.TargetEntry` to the drag source/destination which contains
+ a :class:`GdkPixbuf.Pixbuf`.
+
+ .. method:: drag_source_add_uri_targets()
+ drag_dest_add_uri_targets()
+
+ Add a :class:`Gtk.TargetEntry` to the drag source/destination which contains
+ a list of URIs.
+
+.. class:: Gtk.IconView
+
+ .. method:: enable_model_drag_source(start_button_mask, targets, actions)
+
+ Arguments are the same as :meth:`Gtk.Widget.drag_source_set`
+
+ .. method:: enable_model_dest_source(targets, actions)
+
+ Arguments are the same as :meth:`Gtk.Widget.drag_dest_set`
+
+.. class:: Gtk.TargetEntry
+
+ .. staticmethod:: new(target, flags, info)
+
+ Creates a new target entry.
+
+ *target* is a string describing the type of data the target entry describes.
+
+ *flags* controls under which conditions will the data be transferred in a
+ drag and drop and is a combination of the :attr:`Gtk.TargetFlags` values:
+
+ * :attr:`Gtk.TargetFlags.SAME_APP` - Only transferred in the same application
+ * :attr:`Gtk.TargetFlags.SAME_WIDGET` - Only transferred within the same widget
+ * :attr:`Gtk.TargetFlags.OTHER_APP` - Only transferred in a different application
+ * :attr:`Gtk.TargetFlags.OTHER_WIDGET` - Only transferred within a different widget
+
+ *info* is an ID which the application can use to determine between different
+ pieces of data contained in a drag and drop operation.
+
+.. class:: Gtk.SelectionData
+
+ .. method:: get_text()
+
+ Returns the contents of the text contained in selection data
+
+ .. method:: set_text(text)
+
+ Sets the contents of the text contained in selection data to *text*
+
+ .. method:: get_pixbuf()
+
+ Returns the pixbuf contained in selection data
+
+ .. method:: set_pixbuf(pixbuf)
+
+ Sets the pixbuf contained in selection data to *pixbuf*
+
+.. _drag-signals:
+
+Drag Source Signals
+-------------------
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+| Name | When it is emitted | Common Purpose |
++====================+==============================================================+====================================================+
+| drag-begin | User starts a drag | Set-up drag icon |
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+| drag-data-get | When drag data is requested by the destination | Transfer drag data from source to destination |
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+| drag-data-delete | When a drag with the action Gdk.DragAction.MOVE is completed | Delete data from the source to complete the 'move' |
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+| drag-data-end | When the drag is complete | Undo anything done in drag-begin |
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+
+Drag Destination Signals
+------------------------
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+| Name | When it is emitted | Common Purpose |
++====================+==============================================================+====================================================+
+| drag-motion | Drag icon moves over a drop area | Allow only certain areas to be dropped onto |
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+| drag-drop | Icon is dropped onto a drag area | Allow only certain areas to be dropped onto |
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+| drag-data-received | When drag data is received by the destination | Transfer drag data from source to destination |
++--------------------+--------------------------------------------------------------+----------------------------------------------------+
+
+Example
+-------
+
+.. image:: ../images/drag_and_drop_example.png
+.. literalinclude:: ../examples/drag_and_drop_example.py
+ :linenos:
View
1 source/index.txt
@@ -46,6 +46,7 @@ Contents:
textview
menus
dialogs
+ drag_and_drop
stock
Indices and tables
View
8 source/treeview.txt
@@ -257,6 +257,14 @@ TreeView Objects
Gets the :class:`Gtk.TreeSelection` associated with this tree view.
+ .. method:: enable_model_drag_source(start_button_mask, targets, actions)
+
+ Arguments are the same as :meth:`Gtk.Widget.drag_source_set`
+
+ .. method:: enable_model_dest_source(targets, actions)
+
+ Arguments are the same as :meth:`Gtk.Widget.drag_dest_set`
+
TreeViewColumn Objects
^^^^^^^^^^^^^^^^^^^^^^

0 comments on commit 8b1b9e0

Please sign in to comment.
Something went wrong with that request. Please try again.