in reply to Re: Right-click Edit/Paste in TK Browse Entry
in thread Right-click Edit/Paste in TK Browse Entry

As this one seems to have stumped (or bored) the monks, here's my final optimal(?) solution, tested on Windows, OS-X and Linux for adding a right mouse popup "Edit" menu to Widgets like Tk::Entry and Tk::BrowseList which don't already have such a feature.
#!/usr/bin/perl -w # Demo right mouse click activated cut and paste # on Tk widgets that don't have it, like Tk::Entry. # use strict; use warnings; use Tk; my ($txt1, $txt2); MAIN: { Tk::CmdLine::SetArguments(qw(-geometry +410+300)); my $win = MainWindow->new(-title=>'Cut and Paste Demo'); my $frame = $win->Frame; my $f1 = $frame->Entry(-textvariable=>\$txt1, -width=>64, ); my $f2 = $frame->Entry(-textvariable=>\$txt2, -width=>64, ); $f1->grid(-row=>1, -column=>1, -padx=>10, -pady=>10, ); $f2->grid(-row=>2, -column=>1, -padx=>10, -pady=>10, ); $frame->pack; add_edit_popup($win, $f1); MainLoop; } # # Adds a right-click Edit popup menu to a widget. # sub add_edit_popup { my ($mw, $obj) = @_; my $menu = $mw->Menu(-tearoff=>0, -menuitems=>[ [qw/command Cut/, -command=>['clipboardCut', $obj,]], [qw/command Copy/, -command=>['clipboardCopy', $obj,]], [qw/command Paste/, -command=>['clipboardPaste', $obj]], '', [command=>'Select All', -command=>[ sub { $_[0]->selectionRange(0, 'end'); }, $obj, ]], [command=>'Unselect All', -command=>[ sub { $_[0]->selectionClear; }, $obj, ]], ]); $obj->menu($menu); $obj->bind('<3>', ['PostPopupMenu', Ev('X'), Ev('Y'), ]); return $obj; } __END__
If anyone can improve it, or sees potential problems with it, I'd appreciate a post.

Replies are listed 'Best First'.
Re^3: Right-click Edit/Paste in TK Browse Entry
by phatWares (Initiate) on Jul 03, 2012 at 21:03 UTC

    First, I'd like to thank you for this info! I've been using Perl for quite a while, but being self-taught means that sometimes I have to use "cookbook" code that I don't completely understand. On to my comment/question ...

    I tried using the "add_edit_popup" sub in my Tk app. It works great for Tk widgets that are in global scope. I pass into "add_edit_popup" my globally scoped MainWindow along with whatever globally scoped widgets, and it works like a charm!

    The problem is when I try to do the same with locally scoped Tk widgets that are in a sub. For example, I have a sub that withdraws the root MainWindow and creates a new MainWindow populated with widgets. When I make a call to "add_edit_popup" from within this sub (passing in the local MainWindow and Entry widgets), I get an error saying something along the lines of "can't call 'menu' without package or object reference".

    Is this something anyone can answer from what I've described? If not, I'm happy to cook up some sample code to reproduce this problem.

    First time poster but long time researcher here. Thanks so much for any help!

      Welcome, see The Perl Monks Guide to the Monastery, new questions go in Seekers Of Perl Wisdom, because the person whom you're asking a question was last here 46 weeks ago

      Is this something anyone can answer from what I've described?

      Absolutely, see

      $ perl -Mdiagnostics -e " rand()->menu " Can't call method "menu" without a package or object reference at -e l +ine 1 (#1) (F) You used the syntax of a method call, but the slot filled by t +he object reference or package name contains an expression that retur +ns a defined value which is neither an object reference nor a package n +ame. Something like this will reproduce the error: $BADREF = 42; process $BADREF 1,2,3; $BADREF->process(1,2,3); Uncaught exception from user code: Can't call method "menu" without a package or object reference + at -e line 1. at -e line 1.

      That may or may not help you :)

      If not, I'm happy to cook up some sample code to reproduce this problem.

      That is the general idea behind How do I post a question effectively?. Write-it up and post in Seekers Of Perl Wisdom

        Thanks for your reply! I'm just here to say that I figured out (sort of) what was causing the problem ...

        my $mw = MainWindow->new(); my $widget = $mw->SomeWidget(\%some_options)->pack()->focus(); &add_edit_popup($mw, $widget); $mw->MainLoop;

        This will fail. However ...

        my $mw = MainWindow->new(); my $widget = $mw->SomeWidget(\%some_options)->pack(); &add_edit_popup($mw, $widget); $mw->MainLoop;

        This will succeed. The difference is not placing the focus() call in the declaration of the widget. If you do it later in the code using ...

        $widget->focus();

        Then you're golden!

        I'm sure there's a perfectly good explanation for this behavior. What that might be is beyond my Perl knowledge.

        Anyway, BIG thanks to all for your help!