Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Perl is able to deal with Drag-n-Drop within Tk and another applications

by Courage (Parson)
on Dec 22, 2004 at 21:56 UTC ( [id://416925]=perlmeditation: print w/replies, xml ) Need Help??

After some discussion at Tk Drag and Drop Between Applications I tried to find a solution, succeeded, and now I want to bring this experience to a broader audience, so to share experience on how to solve this task.

Saying Tk I mean Tcl/Tk and Perl module Tcl::Tk, but not perlTk.

In order to use this approach Tcl::Tk from CPAN should be installed, Tcl/Tk should also be installed, and Tcl/Tk installation should have tkdnd module http://sourceforge.net/projects/tkdnd/

A self-explaining example is as follows:

use strict; use Tcl::Tk; my $status = ''; my $mw = Tcl::Tk::MainWindow("Simple Drag & Drop Demo..."); # label widget that will show status my $lab_stat = $mw->Label(-textvariable=>\$status, qw/-relief sunken -bd 1 -width 60 -anchor w/)->pack(qw/-side bottom -fill x/); # three more widgets that will be used for trying DND my $lab_source = $mw->Label(-text=>"source", qw/-relief groove -bd 2 -width 20/) ->pack(-pady=>5); my $lab_text_plain = $mw->Label(-text=>"drop plain text", qw/-relief raised -bd 1 -width 20/)->pack(-pady=>5); my $lab_t2 = $mw->Label(-text=>"drop color", qw/-relief raised -bd 1 -width 20 -bg lightyellow/)->pack(-pady=>5); # and a frame $mw->Frame(-height=>10)->pack(qw/-side bottom -fill x/); # following line will do 'package require tkdnd' in Tcl/Tk $mw->interp->need_tk('tkdnd'); # in order to make DND syntax shorter let's define following methods sub Tcl::Tk::Widget::dndBindsource { my $w = shift; $w->interp->call('dnd','bindsource',$w,@_); } sub Tcl::Tk::Widget::dndBindtarget { my $w = shift; $w->interp->call('dnd','bindtarget',$w,@_); } # could be done without above two methods that go to Tcl::Tk package: # $int->call('dnd','bindsource',$widget->path,.....); # but now we will be allowed to shorter # $widget->dndBindsource(....); #--------------------------------------------------------------------- # Before registering a drop target, we always have to make sure the # corresponding widget has been created: $mw->update('idle'); # tells the DND protocol source can deliver textual data $lab_source->dndBindsource('text/plain', q{return "testing DND"}); # bind the DND operation on left button $lab_source->bind('<1>', 'dnd drag %W'); # tells the DND protocol target can handle textual data $lab_text_plain->dndBindtarget('text/plain', '<Drop>', \\'WDTA', sub { my (undef,$int,$sub) = (shift,shift,shift); my ($W,$D,$T,$A) = (@_); # Ev vars my $receiver_widget = $int->widget($W); $receiver_widget->configure(-text=>$D); $status = "[target1] type='$T', action='$A'"; $int->after(2000, sub { $receiver_widget->configure(-text=>"drop plain text") }); }); # defines an other type on source $lab_source->dndBindsource('TK_COLOR', q{return "pink"}); # tells the DND protocol target can handle color data $lab_t2->dndBindtarget('TK_COLOR', '<Drop>', , \\'WDTA', sub { my (undef,$int,$sub) = (shift,shift,shift); my ($W,$D,$T,$A) = (@_); # Ev vars $lab_t2->configure(-bg=>$D); $status = "[target1] type='$T', action='$A'"; $int->after(2000, sub {$lab_t2->configure(-bg=>'lightyellow')}); }); Tcl::Tk::MainLoop;

And, since we're talking in TIMTOWTDI language, here is alternate approach: same logic but here we wrap Tcl/Tk-only GUI which is still available with perlTk syntax

use strict; use Tcl::Tk; my $mw = Tcl::Tk::tkinit; $mw->interp->Eval(<<'EOS'); package require tkdnd ## Iconify ".". We are going to add windows and call update many times +. ## Avoid some interesting visual effects :-) wm withdraw . #--------------------------------------------------------------------- +--------- # Step 1: A simple Drag Source #--------------------------------------------------------------------- +--------- # create the source window label .source -text "source" -relief groove -bd 2 -width 20 pack .source -pady 5 # tells the DND protocol source can deliver textual data dnd bindsource .source text/plain {return "testing DND"} # bind the DND operation on left button bind .source <1> {dnd drag %W} #--------------------------------------------------------------------- +--------- # Step 1: A simple Drop Target accepting plain text #--------------------------------------------------------------------- +--------- # defines the target window label .text_plain -text "drop plain text" -relief raised -bd 1 -width +20 pack .text_plain -pady 5 # Before registering a drop target, we always have to make sure the # corresponding widget has been created: update idle # tells the DND protocol target can handle textual data dnd bindtarget .text_plain text/plain <Drop> \ {%W configure -text %D; status "\[target1\] type='%T', action='%A'" after 2000 {%W configure -text "drop plain text"}} #--------------------------------------------------------------------- +--------- # Step 2: Management of multiple types on the source #--------------------------------------------------------------------- +--------- # defines an other type on source dnd bindsource .source TK_COLOR {return "pink"} # defines a target window label .target2 -text "drop color" -relief raised -bd 1 -width 20 \ -bg lightyellow pack .target2 -pady 5 # tells the DND protocol target can handle color data dnd bindtarget .target2 TK_COLOR <Drop> { status "\[target2\] type='%T', data='%D', action='%A'" .target2 configure -bg %D after 2000 ".target2 configure -bg lightyellow" } #===================================================================== +========= # END #===================================================================== +========= proc status {msg} { .status configure -text $msg } proc init {} { wm title . "Simple Drag & Drop Demo..." label .status -relief sunken -bd 1 -width 60 -anchor w pack .status -side bottom -fill x pack [frame .sep -height 10] -side bottom -fill x pack propagate .status 0 } init update wm deiconify . EOS # Tcl inclusion for GUI finished here; you can work with widgets here +like: # my $lab = $mw->interp->widget('.status'); # $lab->configure(-text=>'new text here...'); Tcl::Tk::MainLoop;
Both approaches are cross-platform, easy-to-use.
Both allow drag-n-drop interaction with non-Tk applications.

Best regards,
Courage, the Cowardly Dog

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://416925]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-12-09 09:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which IDE have you been most impressed by?













    Results (53 votes). Check out past polls.