Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Tk - finding what's being pointed at

by Chuma (Scribe)
on Nov 26, 2016 at 03:56 UTC ( [id://1176576]=perlquestion: print w/replies, xml ) Need Help??

Chuma has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to make my first graphical thing in Tk, but I'm having trouble getting a reference to what's under the mouse pointer. From what I gather, it seems like the easiest way should be $canvas->find('withtag','current'), but I can't get anything out of it. I've boiled it down to an example:

use feature(say); use Tk; #create a couple of arbitrary widgets $main=MainWindow->new; $can=$main->Canvas(-width => 600, -height => 400)->pack; $lab=$can->Label(-text => "AAAAAAAA")->place(-x=>100,-y=>100); $but=$can->Button(-text => "BBBBBBBB")->place(-x=>300,-y=>150); #use a key binding to invoke an event $main->bind('<KeyPress-a>',sub{ say $can->find('withtag','current'); #nothing! }); MainLoop;

I point at things and press "a", but apparently it's not finding anything - "say" just prints an empty line. I tried a few other things, for example the slightly more roundabout $can->find('closest',$can->pointerx,$can->pointery), which gives the same result.

Meanwhile, say $can->pointerx; works fine, so I guess I could implement my own search through the widgets, but that seems a little too roundabout for my taste.

What am I missing?

Replies are listed 'Best First'.
Re: Tk - finding what's being pointed at
by kevbot (Vicar) on Nov 26, 2016 at 07:38 UTC
    Hello Chuma,

    I was able to find a solution with some help from Re: Determine canvas object under click (Tk), and Mastering Perl Tk Chapter 9.6 - Creating Items in a Canvas - The Widget Item.

    #!/usr/bin/env perl use strict; use warnings; use feature qw/say/; use Tk; #create a couple of arbitrary widgets my $main = MainWindow->new; my $can = $main->Canvas(-width => 600, -height => 400)->pack; my $lab = $can->Label(-text => "AAAAAAAA"); my $but = $can->Button(-text => "BBBBBBBB"); # The Label and Button methods used above do not have a '-tags' option +. So as # suggested by Mastering Perl/Tk, the createWindow method can be used +to add # tags $can->createWindow(100, 100, -window => $lab, -tags => ['MyLabel']); $can->createWindow(300, 150, -window => $but, -tags => ['MyButton']); # use a key binding to invoke an event $main->bind('<KeyPress-a>',sub{ # The method used below was shown in: # http://www.perlmonks.org/?node_id=987386 $can->addtag( qw/current closest/, $Tk::event->x, $Tk::event->y ); my @tags = grep {$_ ne 'current'} $can->gettags(qw/current/); $can->dtag(qw/current current/); say @tags; }); MainLoop;
Re: Tk - finding what's being pointed at
by Discipulus (Canon) on Nov 26, 2016 at 19:37 UTC
    hello Chuma,

    I'm not a master but, as you are starting with Tk maybe your are, if i'm permitted, misunderstanding something, or i misunderstand your question.

    I mean that generally you do not care about where the cursor is, it's x and y , infact for your commodity you let the Tk geometry manager you have choosen to place your widget for you.

    Infact when you create widget sensible to mouse like buttons you can specify directly an action to actuate when the button is clicked. You have not to care where the button is.

    In the Tk world this is called callback and is a sub associated within the -command argument that many widgets support.

    $mw->Button(-text => 'Quit', -command => sub { print 'Bye!'; exit; + })->pack;

    By other hand keybinding are callbacks invoked to response to a keyboard event. In the following example you are saying that, for $mw , when the key a is released the Mainloop is charged to call a callback.

    $mw->bind('<KeyRelease-A>' => \&print_something);

    Obviously grabbing coordinates is possible in Tk and canvas are well suited to the task but is, in my opionion, an advanced usage not need in common Tk interfaces.

    I have reduced this code to a simpler example to demonstrate how you can grab mouse coordinates when Button-1 of the mouse is pressed. It uses the advanced CanvasBind and grab Ev events printing coordinates to the terminal:

    #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = MainWindow->new; $mw->geometry("700x600"); my $canvas = $mw->Canvas->pack(-fill=>'both', -expand=>'both' ); $canvas->CanvasBind("<Button-1>", [ \&print_xy, Ev('x'), Ev('y') ]); MainLoop; sub print_xy { my ($canv, $x, $y) = @_; print "(x,y) = ", $canv->canvasx($x), ", ", $canv->canvasy($y), "\n" +; }

    The original code is by zentara: you can SuperSearch all his code here around and learn a lot of things being a real master in Tk and many other fields.

    In my learn path I found, recently, two modules very useful to understand many apsects of Tk

    use Tk::WidgetDump; use Tk::ObjScanner; # and later Tk::ObjScanner::scan_object($the_widget_or_window_to_inspect);

    HtH

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1176576]
Approved by Athanasius
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-04-23 18:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found