TkinterDnD reference manual

1. Drag and drop methods

2. Canvas drag and drop methods

3. Shape methods

4. DnD Events

5.The CursorWindow class

6. TkinterDnD constants

On importing the TkinterDnD module, it is safe to do:
    from TkinterDnD import *
After that drag and drop support can be initialized by creating a drag and drop capable root window:
    root = TkinterDnD.Tk()
If you want to make use of the Tix widgets, use instead:
    root = TkinterDnD.TixTk()
This will create a new instance of a Tkinter.Tk (resp. Tix.Tk) window with additional dnd and shape methods; the dnd and shape methods are also passed to any of the root window's child widgets.
The following aditional methods are available:

Drag and drop methods:

The dnd methods provide a Tkinter interface to native, platform specific drag and drop mechanisms. Under unix the drag & drop protocol in use is the XDND protocol (also used by the QT toolkit, KDE & GNOME Desktops). Basic interaction (currently drops) with Motif applications is also provided. Under Windows, the OLE drag & drop interfaces are used. The Macindosh platform is not yet supported.
With the dnd_...() commands the user is able to register existing Tk widgets as drag sources or drop targets, that are able to send or receive data encoded in specific types. Also through these commands drag and drop related information can be retrieved, regarding the drag and drop registered widgets.
DRAG AND DROP TYPES
In order to declare the format that the data that will be encoded during a drag and drop operation, all drag and drop protocols use the notion of types. Unfortunately, each protocol defines its own, usually platform specific, types. The Tk toolkit, trying to maintain its portability among different platforms, offers some predefined types for some basic kinds of data, like text, filenames and images. These types are represented by their MIME types and are available under all platforms that Tk is available. Currently, the following predifined values are available: Besides the predefined types, the user is free to use the platform specific types. For example under windows the type "FILENAME" can be used in order to receive a single filename from the Explorer or the type "NetscapeURL" can be used in order to receive a bookmark drop from Netscape Navigator. Under Unix, the type "FILE_NAME" can be used in order to receive a filename from a Motif application. The dnd commands will make no conversion to types other than the predefined ones. Instead it will place received data into tcl byte-arrays and extract data from tcl after it converts objects into byte-arrays. Also note that the script should make the proper arrangements in order to maintain portability under different platforms. Procceed with platform depended types only if you are absolutely sure that the data you want to exchange is not supported by the predefined, platform independed, types.

The following dnd methods are available on windows and unix systems:

dnd_askselectedaction(self, x, y, actions, descriptions):

May be abbreviated as askselectedaction().
Pops up a menu at window coordinates X, Y that allows the user to select the desired action from the given tuple ACTIONS with the associated tuple DESCRIPTIONS as menu labels. The return value is the selected action or NONE if the drop was cancelled.

dnd_bindsource(self, dndtype=None, callback=None, priority=None):

May be abbreviated as bindsource().
This command will register a CALLBACK for the specified DNDTYPE. This CALLBACK will be used during a drop operation, in order to provide the actual data that will be dropped to the drop target. As a result, this CALLBACK must return the data to be dropped and the returned data must be encoded in a proper format, according to the specified DNDTYPE.
If the CALLBACK is an empty string, then the specified DNDTYPE will be removed from the type list of supported by the drag source types.
Finally, the user can arrange the types that the drag source supports according to priorities. Valid priorities are integers in the range [1,100], with 100 denoting the highest possible priority. If priority is ommited, it defaults to 50. If more than one types have the same priority, only one of them will be used for a drop action. In this case the actual type that will be used cannot be pre-determined.
If CALLBACK is None, dnd_bindsource() will return the binding script that will be used for collecting the data that will be dropped during a drop operartion onto the drop target. Each script is associated with a specific DNDTYPE, providing the ability to have different scripts for different types.
If both CALLBACK and DNDTYPE are None, dnd_bindsource() will return a list of all the registered types that SELF can drop on drop targets during a drop operation. An empty list will be returned if SELF is not yet registered as a drag source.

dnd_bindtarget(self, dndtype=None, sequence=None, callback=None, priority=None):

May be abbreviated as bindtarget().
This command will register a CALLBACK for the event specified by SEQUENCE and for the specified DNDTYPE. Valid events are any of the following events: <DragEnter>, <Drag>, <DragLeave>, <Ask> and <Drop>. The events support modifiers as in Tk. You can use a combination of Shift, Alt, Meta, Control, Mod[1-5], Button[1-5] to bind specific scripts when these modifiers are used. As in Tk, the closest matching script will be executed. If there is no exact match, the following algorithm will be applied: find an event without key modifiers but with buttons modifiers, then find an event without buttons modifiers but with the key modifiers, then at last find an event without key modifiers and without buttons (i.e. a raw event as listed above).
The <DragEnter> event will be delivered when the mouse enters SELF during a drag operation. The <Drag> event will be delivered when the mouse moves inside the widget during a drag operartion and the <DragLeave> event will be delivered if the mouse pointer leaves the widget during a drag operation. Finally, the <Drop> event will be delivered if a drop over SELF occurs.
If there is already a binding script for the same event, this script is replaced by the new one. If CALLBACK is an empty string, then any previous binding script is deleted and the specified event is no longer reported to SELF.
The user can optionally specify a PRIORITY for this specific DNDTYPE (an integer value ranging from 1 to 100). Priorities have meaning only when more than one types are registered for the same event. During a drag operartion the specified event will be delivered by executing the binding script associated with the DNDTYPE that has the higher priority (or the lower integer value: priority 1 is the highest priority while 100 is the lowest available priority). If PRIORITY is ommited, it defaults to 50. If more than one types have the same priority, the actual type that will be used cannot be pre-determined.
If CALLBACK is None, dnd_bindtarget() will return the binding script for the specified SEQUENCE. If SEQUENCE is not specified, it defaults to the <Drop> event. An empty string will be returned if SELF is not yet registered as a drop target.
If DNDTYPE, SEQUENCE and CALLBACK are None, dnd_bindtarget() will return a list of all the registered types that SELF can accept during a drop operation. An empty list will be returned if SELF is not yet registered as a drop target.

dnd_clearsource(self):

May be abbreviated as clearsource().
This command will unregister a registered drag source. Subsequent attempts to initiate drag operations from this widget with the dnd_drag() command will fail. The callback associated for retrieving the data will be removed. It is not an error to use this command on a widget that has never been registered as a drag source.

dnd_cleartarget(self):

May be abbreviated as cleartarget().
This command will unregister a registered drop target. The widget will stop to respond to drops and all callbacks for all drop target related events will be removed. It is not an error to use this command on a widget that has never been registered as a drop target.

dnd_drag(self, actions=None, descriptions=None, cursorwindow=None, callback=None, button=None):

May be abbreviated as drag().
This command will initiate a drag operation having as source a widget registered as a drag source. It is an error to use this command with a widget that has not been registered as a drag source.
The user can also specify a CURSORWINDOW. A Cursor window is a toplevel window that will appear near the mouse cursor and will follow the cursor, as the mouse cursor moves during the drag operation. This window must exist when the dnd_drag() command will be executed. If a Cursor window is specified, the user can also register a callback through the CALLBACK option. This CALLBACK will be called when the mouse pointer is moved and can be used in order to update the contents of the widget. A DnDEvent instance will be passed as first argument to this callback.
One difference with the usual events is that in this context, the event.action attribute can also take as value the empty string, meaning that the cursor is over a widget that cannot accept a drop action. It is advised that this particular callback should be as fast as possible, as it is called very frequently. That is also the reason why the position of the cursor window is managed by the dnd_drag() command. Also, the dnd_drag() command ensures that the cursor window will always be visible (above all other windows).
Finally, the user can optionally specify a tuple of ACTIONS that will be associated with the current drag and drop operation. Valid actions are the following: COPY, MOVE, LINK and ASK. It is up to the drop target to decide which action will be actually used for the drop operation. It is also responsibility of the drop target to do the required actions implied by the drop action. For example, if the drop action during a file name drop is MOVE, the widget that accepts the drop is responsible for deleting the old file and create the new file at the dropped location.
If the ASK action is included in the specified action list, then a DESCRIPTIONS tuple can be also specified. The meaning of the ASK action is that when the drop finally occurs, the widget that will accept the drop should display a window that will enable the user to select the action that is desired from the available list. The ASK action should not be listed and also a way to cancel the drop should be provided to the user. The descriptions provided with the description list are the text that should be displayed for the corresponding individual action entries in the presented window. As a result, the description list must contain the same number of items as the action list and its text elements must describe the corresponding actions specified by the ACTIONS option. For example, a drop that offers all available actions should be defined as follows:
    widget.dnd_drag(actions=(ASK, COPY, MOVE, LINK), descriptions=('Please select action:', 'Copy', 'Move', 'Link'))


Canvas drag and drop methods:

To enable the user to bind drag and drop events to items on a canvas widget, there are some canvas specific dnd methods:

dnd_canvas_deliver_event_ask(self, event):

May be abbreviated as deliver_event_ask().
Finds the canvas item over which EVENT occured and invokes the callback bound to <Ask> events for this item (if present) with EVENT as first argument.
This is equivalent to dnd_canvas_deliver_event(self, "<Ask>", event).

dnd_canvas_deliver_event_drag(self, event):

May be abbreviated as deliver_event_drag().
Finds the canvas item over which EVENT occured and invokes the callback bound to <Drag> events for this item (if present) with EVENT as first argument.
This is equivalent to dnd_canvas_deliver_event(self, "<Drag>", event).

dnd_canvas_deliver_event_dragenter(self, event):

May be abbreviated as deliver_event_dragenter().
Finds the canvas item over which EVENT occured and invokes the callback bound to <DragEnter> events for this item (if present) with EVENT as first argument.
This is equivalent to dnd_canvas_deliver_event(self, "<DragEnter>", event).

dnd_canvas_deliver_event_dragleave(self, event):

May be abbreviated as deliver_event_dragleave().
Finds the canvas item over which EVENT occured and invokes the callback bound to <DragLeave> events for this item (if present) with EVENT as first argument.
This is equivalent to dnd_canvas_deliver_event(self, "<DragLeave>", event).

dnd_canvas_deliver_event_drop(self, event):

May be abbreviated as deliver_event_drop().
Finds the canvas item over which EVENT occured and invokes the callback bound to <Drop> events for this item (if present) with EVENT as first argument.
This is equivalent to dnd_canvas_deliver_event(self, "<Drop>", event).

dnd_canvas_deliver_event(self, sequence, event):

May be abbreviated as deliver_event().
Finds the canvas item over which EVENT occured and invokes the callback bound to SEQUENCE for this item (if present) with EVENT as first argument.
The return value is the value returned by this callback or "break" if no such callback exists or no canvas item is under the mouse pointer.
This method can be used in combination with dnd_tag_bindtarget() to define canvas items as drop targets. This is neccessary because drag and drop events can only be bound to a widget as a whole, not to canvas items.
For standard drag and drop events the shortcut methods dnd_canvas_deliver_event_ask() etc. can be used instead. If you want to use drag and drop events with event modifiers it may be useful to use this command to write handlers like e.g.:
    def dnd_canvas_deliver_event_shiftdrag(self, event):
        return self.dnd_canvas_deliver_event("<Shift-Drag>", event)

dnd_tag_bindtarget(self, tagOrId, sequence=None, callback=None):

May be abbreviated as tag_bindtarget().
Binds CALLBACK for the specified SEQUENCE to the canvas item defined by TAGORID. This should be combined with a binding of the canvas widget for SEQUENCE to dnd_canvas_deliver_event() resp. to the shortcut method appropriate for SEQUENCE.

Shape methods:

The shape methods allow to handle shaped, i.e. non-rectangular windows (unix systems only).

Kinds of shape
Every window has two kinds of shape; their bounding and their clipping shapes. The bounding shape of a window describes the area covered by that window, and the clipping shape of a window describes the part of the window occupied by the contents of that window. The area of the window contained in the bounding area of the window but not in the clipping area of the window is the border of the window. This border is not useful under Tk (which manages all widget borders internally,) so the default kinds that the various operations work on are such that read-only operations work by default on the bounding shape (via the KIND=BOUNDING option) and read-write operations work by default on both the clip and the bounding shapes (via the KIND=BOTH option.) The KIND=CLIP option is unlikely to be useful in normal operation.
Shape sources
There are five types of shape sources: Caveats
When setting the shape of a toplevel window, make sure that you perform an update_idletasks() between the creation of the toplevel and applying a shape_set() or shape_update() operation to it. This is because Tk works by reparenting toplevel windows into a (user-invisible) container, so allowing the introduction of a menubar to windows without having to alter the internal dimensions of the toplevel. Because this is done on an idle handler, you must wait until after that idle handler has executed before applying a reshape operation to a toplevel. Failure to do this will result in the reshaped toplevel being apparently encased in a toplevel window that is unresponsive to all events (like <Expose> events). While no harm is done to the application, this an undesirable effect that you probably do not want in your application. This extension can only handle applications that use a single screen, or at least, it can only handle those that only attempt to use shaped windows on the same screen as . Since this is the vast majority of all applications, this should not prove too onerous a restriction for the present.
Updating window shapes can be a very expensive operation, so you are advised to avoid doing it as much as possible (do not use it as a way of doing animation - it does not work well.) Of course, if you need to change the shape, then do so, but you should try to find ways that do it as little as possible due to it being an expensive operation. Some other X clients can run far slower if they have to interact with shaped windows. The troublemakers are not always the clients that you would expect to cause problems.

The following shape methods are available:

shape_bounds(self, kind='bounding'):

Returns the bounding box of the shape of self, or None if the window does not currently have a shape set for it (i.e. it is rectangular.) The kind option allows the selection of which shape to retrieve the bounding box of. If set to BOUNDING the bounding shape of the window is to be queried (the default.) If set to CLIP the clipping shape of the window is to be queried.

shape_get(self, kind='bounding'):

Returns a list of rectangles describing the shape of self. If self currently has no shape set for it, this command returns the Xserver's current idea of the rectangular shape of self which might or might not be "sensible". The kind option allows the selection of which shape to retrieve the shape of. If set to BOUNDING the bounding shape of the window is to be queried (the default.) If set to CLIP the clipping shape of the window is to be queried.

shape_offset(self, x, y, kind='both'):

Moves the shape of self by x pixels right and y pixels down, relative to the overall position of self . The contents of self do not move. The kind option allows the selection of which shape to move. If set to BOUNDING the bounding shape of self is to be moved. If set to CLIP the clipping shape of self is to be moved. If set to BOTH (the default), both the bounding and the clipping shapes of self are moved.

shape_set(self, sourcekind, source=None, offset=None, kind='both'):

Sets the shape of self to the shape specified by the source described by sourcekind , possibly pre-offset by offset=(xOffset, yOffset), much as in the shape_offset() command. The kind option allows the selection of which shape to set. If set to BOUNDING the bounding shape of self is to be set. If set to CLIP the clipping shape of self is to be set. If set to BOTH (the default), both the bounding and the clipping shapes of the window will be set.

shape_update(self, operation, sourcekind, source=None, offset=None, kind='both'):

Updates the shape of self, applying a shape using set operation operation. The shape applied is specified by the source described by sourcekind and is possibly pre-offset by offset=(xOffset, yOffset), much as in the shape_offset() command. The kind option allows the selection of which shape to set. If set to BOUNDING the bounding shape of self is to be set. If set to CLIP the clipping shape of self is to be set. If set to BOTH (the default), both the bounding and the clipping shapes of self will be set.
The following set operations are supported:

shape_version(self):

Returns the version number of the non-rectangular window extension installed on the X server that serves the screen that "." is on. Note that this is not the version number of the Tcl/Tk extension.

DnD Events

An instance of the DnDEvent class is a container for the properties of a drag-and-drop event. This is very similar to a Tkinter.Event, except that a DnDEvent holds a different set of attributes. Instances of this type are generated if one of the following events occurs: <DragEnter>, <Drag>, <DragLeave>, <Ask>, <Drop>.

Drag and drop events
There are four events that are associated with drop targets and a single event associated with drag sources. If a callback function for one of these events is registered using dnd_bindtarget(), or dnd_bindsource(), the callback is called with a DnDEvent instance as first argument. It will have the following attributes:

The CursorWindow class

Convenience class to create a cursor window, i.e. a window that displays a "file" icon that moves next to the mouse pointer during drag and drop operations.
Usage example:
    def start_dnd(event):
        cw = TkinterDnD.CursorWindow()
        event.widget.dnd_drag(actions=(ASK,COPY,MOVE, LINK), cursorwindow=cw,
                              descriptions=('Please select action:','Copy', 'Move', 'Link'))
        cw.destroy()

    sourceWidget.bind('<1>', start_dnd)
The CursorWindow() constructor allows to define a custom image to be used via the bitmap and image arguments; the bitmap bitmap will be used to calculate the shape for the window. This is necessary, because shapes cannot be determined from image data. As a consequence of this, bitmap and image should be of the same dimensions in order to get the expected results. bitmap must be a valid Tk bitmap string and image must be a Tkinter.PhotoImage or Tkinter.BitmapImage. The offset argument allows to pass a tuple of x- and y-coordinates that will be used as coords in create_image(); the use of this option may depend on the image in use. offset defaults to (4, 4).

CursorWindow attributes:

An instance cw of the CursorWindow class has the following attributes (besides standard Tkinter.Toplevel attributes):
Besides standard Toplevel methods the CursorWindow class has the following methods:

image(self, newimage):

Convenience method to change the image the cursor window displays. Usefulin the first place if you have a predefined set of images of the same dimensions that should be displayed in different situations. This is equivalent to self.canvas.itemconfigure(self.icon, image=newimage). newimage must be a Tkinter.PhotoImage or Tkinter.BitmapImage .


TkinterDnD constants

The TkinterDnD module defines a few useful constant names that from TkinterDnD import * adds to the global namespace, similar as in Tkinter:
  1. Drag and drop actions:
  2. Drag and drop types:
  3. Kinds of shapes:
  4. Types of shape sources:
  5. Shape set operations: