The New - Drag and Drop with Perl/Tk
The New  
Monday, 21 April 2014
Main Menu
Perl/Tk Widgets
Useful Tips
Contact Us
Login Form


Remember me
Forgotten your password?
No account yet? Create one
Drag and Drop with Perl/Tk PDF Print E-mail
Written by Slaven Rezic   

A useful interface for communication between GUI programs is the drag and drop facility. This interface can also be used for actions inside an application, e.g. for moving items from one place to another. Perl/Tk supports drag and drop, and since the documentation in the distribution is a little sparse on this topic, I will provide some information in this article.

A user who wants to implement drag and drop in his Perl/Tk application has to deal with the following concepts:

  • The drag source: the widget where a drag action starts (by pressing the mouse button on the item to be moved and moving the mouse).
  • The drag token: this is a widget, which is moved by the mouse cursor from one location to another. This can be a label with text or an image.
  • The dropsite: this is a widget in the GUI which will accept drops.

In Perl/Tk, two types of drag and drops are implemented: local drops and drops from other applications. Local drops work on all supported platforms. Drops between applications are not standardized, so there is a number of drag and drop protocols. Perl/Tk supports these protocols: Sun, XDND, KDE and Win32. The Sun protocol is supported since the old days. Win32 support is added in the version 800.005, while the KDE and XDND support is fairly new: they appeared in the latest 800.015 release. KDE drag and drop is used by the KDE file manager kfm. XDND is a protocol developed by and is used in GNOME. It is expected that KDE will also switch to XDND in the future.

The drag and drop interface is fairly low-level, as it works using X11 selections. There are some limitations (the interface only works for single files and does not support anything else than filenames, that is, drops using URLs in KDE will not work). There is also rumor that there will be changes in the Tcl/Tk core to support drag and drop, so it is likely that this changes will appear some day in Perl/Tk, too. Nevertheless, the current interface in Perl/Tk is working and useful.

Local drops


 Here is a sample script for local drag and drop. In this example two listboxes are created. Items from the left listbox can be dragged to the left one.

For local drops we need either the source and the target side, so both drag and drop modules should be included in the script: Tk::DragDrop (for the source) and Tk::DropSite (for the target). The source side is defined by calling the DragDrop method on the source widget. The following options should be set:

  • -event for the event starting a drag action, usually <B1-Motion>, meaning when pressing the left mouse button and moving the cursor.
  • -sitetypes to specify the drag and drop protocol. As we use local drops, we have to set this option to Local.
  • -startcommand specifies the callback which is executed when starting a drag.

The DragDrop method returns a "token", which is a Label widget for the text or image displayed during the drag action.

The target widget is called with the DropSite method. The -droptypes option is used to register the drop type this widget is accepting (here we use again Local) and the -dropcommand option is set to a callback which is executed when a drop occured.

In the example script, the StartDrag is called when a drag is started. This subroutine is responsible for setting the content of the drag token with the configure method. In the sample script, the current item of the listbox is determined with the nearest method. After that the token is placed at the current cursor position and activated with raise and deiconify. Further processing is done in the FindSite method, which is responsible for highlighting the token over a dropsite and to handle a drop action.

The Drop function of the example script accepts a drop and performs an action. Here it uses the text value of the token to add another item to the right listbox.

Remote drops

A sample script for accepting drops from an external application, e.g. the KDE file manager or the Windows explorer.

For accepting drops from an external application, for example a file manager, only a drop site has to be defined. So it's sufficient to include only Tk::DropSite. The command to accept drops is the same as in the example above for local drops. The list of drop types should list all dnd protocols which should be accepted, that is Win32 if running on Windows, otherwise KDE, XDND and Sun.

The accepting callback receives an additional argument which is the name of a selection. This selection is used to get the filename of the drop. For Win32 dnd, we have to look at the "STRING" property, while for all other protocols, the property name is "FILE_NAME". In case of an error (because the property is not defined), the selection get is done in an eval block.

Additional methods

For the source side, the following callbacks can be set:
  • -entercommand: Called if a dropsite is entered.
  • -motioncommand: Called if the token is moved over a dropsite.

Short summary

Here is a short summary for using the drag and drop methods:
# load code for using the source side
use Tk::DragDrop;

# load code for using the target side
use Tk::DropSite;

# define the source side
$target->DropSite(-dropcommand => \&drop_handler,
                  -droptypes   => ['KDE','XDND','Sun','Win32','Local'],

# define the target side
$source->DragDrop(-event => '<B1-Motion>',
                  -sitetypes   => ['KDE','XDND','Sun','Win32','Local'],
                  -startcommand => \&drag_handler,
                  -entercommand => \&enter_handler,
                  -motioncommand => \&motion_handler,

# used in the drag_handler
$token->FindSite($xpos, $ypos, $event);

More information can be found in the DragDrop directory in the source distribution of Perl/Tk. There are some sample scripts: local_test, motion_test and site_test. And if there are still open questions: use the force, read the source!


DnD with Tk::HList


Look at this sample script for drag and drop with Tk::HList. You have to set the -selectmode of the HList to dragdrop. There are more complicated issues, like dealing with trees or multiple columns. Write Comment (0 Comments)

< Prev   Next >
Top! Top!