For Programmers: Free Programming Magazines  


Home > Archive > PerlTk > January 2007 > Canvas->bind with 'Window' items









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Canvas->bind with 'Window' items
Ch Lamprecht

2007-01-12, 7:02 pm

Hi,

I am facing a problem with bindings to Canvas 'Window' items:
The Events triggered over 'Window'-items are caught by the widgets associated
with the item. Now I am searching for an elegant way to redirect these events to
the canvas-widget in order to have them processed the way, the bindings to other
canvas-items are.
Take a look at the following example, two items are created: one tagged
'rectangle_item' and one tagged 'window_item'.
Both have a canvas binding on '<1>'. Both can be triggered. -For the rectangle
simply by clicking on the item, for the (Entry-)window by pressing the button,
which will generate the '<1>' event for the canvas widget.
If you click (<1> ) on the (Entry-)window-item the canvas-binding will not be
triggered. Instead the Entry-widget will receive this event. However calling the
subroutine used by the Button from the widgets event-handling sub, will not
generate an event for canvas in this case.
One dirty workaround is, to use an 'after' call.(Commented out close to the end)
This might work or not, depending on the delay. So that can't be the solution.

Thanks for suggestions, Christoph

use strict;
use warnings;
use Tk;
my $mw =tkinit;

my $can = $mw->Canvas(-width => 300,
-height=> 300)->pack;
my $item = $can->createRectangle(5,5,100,100,
-tags => ['rectangle_item'],
-fill => 'red');
my $wid = $can->Entry(-text=> 'click here to test');
my $w_item= $can->createWindow(200,200,
-tags => ['window_item'],
-window => $wid);
for my $tag(qw/rectangle_item window_item/){
$can->bind($tag,'<1>',
sub{print "canvas binding triggered for $tag with coords:\n";
my $e = $can->XEvent;
my ($x, $y)=($e->x, $e->y);
print "x: $x y: $y\n\n";
});
}

$wid->bind('<1>',
sub{print "widget binding triggered with coords:\n";
my $ev = $wid->XEvent;
print "x: ",$ev->x," y: ",$ev->y,"\n";
# $_[0]->ForwardEvent($can);#does not work - and if it did,
#x and y would be wrong
generate_canvas_event();
}
);

$mw->Button(-text => 'generate event',
-command=> sub{print "Button pressed\n";
generate_canvas_event();
}
)->pack;
MainLoop;

sub generate_canvas_event{
print "trying to generate <1> for canvas:\n";
$can->eventGenerate('<1>',-x => 200, -y => 200);
# a dirty workaround:
#$mw->after(200,[$can,'eventGenerate','<1>',-x=>200,-y=>200]);
print "generated event <1> for canvas!\n";
}


--

perl -e "print scalar reverse q/ed.enilno@ergn.l.hc/"
Slaven Rezic

2007-01-13, 7:02 pm

Ch Lamprecht <ch.l.ngre@online.de> writes:

> Hi,
>
> I am facing a problem with bindings to Canvas 'Window' items:
> The Events triggered over 'Window'-items are caught by the widgets
> associated with the item. Now I am searching for an elegant way to
> redirect these events to the canvas-widget in order to have them
> processed the way, the bindings to other canvas-items are.
> Take a look at the following example, two items are created: one
> tagged 'rectangle_item' and one tagged 'window_item'.
> Both have a canvas binding on '<1>'. Both can be triggered. -For the
> rectangle simply by clicking on the item, for the (Entry-)window by
> pressing the button, which will generate the '<1>' event for the
> canvas widget.
> If you click (<1> ) on the (Entry-)window-item the canvas-binding will
> not be triggered. Instead the Entry-widget will receive this event.
> However calling the subroutine used by the Button from the widgets
> event-handling sub, will not generate an event for canvas in this case.
> One dirty workaround is, to use an 'after' call.(Commented out close
> to the end) This might work or not, depending on the delay. So that
> can't be the solution.


I think the easiest would be to not use eventGenerate at all, but just
to call a common subroutine from both the normal bind subroutine and
the -command subroutine.

This strange behavior does not seem to be a speciality of Perl/Tk.
Tcl/Tk shows the same problem:

pack [canvas .can -width 300 -height 300]
set item [.can create rectangle 5 5 100 100 -tags rectangle_item -fill red]
entry .can.e -text "click here to test"
set w_item [.can create window 200 200 -tags window_item -window .can.e]
.can bind all <1> {puts "hallo %x %y"}
#bind .can.e <1> { puts "window binding %x %y"; event generate .can <1> -x 200 -y 200 }
bind .can.e <1> { puts "window binding %x %y"; after 200 { event generate .can <1> -x 200 -y 200 }}

Maybe you can ask at comp.lang.tcl?

Regards,
Slaven

--
Slaven Rezic - slaven <at> rezic <dot> de

Dump a Tk canvas as an xfig file:
http://search.cpan.org/search?mode=...y=Tk::CanvasFig
Ch Lamprecht

2007-01-13, 7:02 pm

Slaven Rezic wrote:
> Ch Lamprecht <ch.l.ngre@online.de> writes:
>
>
>
>
> I think the easiest would be to not use eventGenerate at all, but just
> to call a common subroutine from both the normal bind subroutine and
> the -command subroutine.


The button and the subroutine were only for the purpose of demonstrating, that
canvas is able to receive and process the event for a tagged window-item.
What I'm looking for, is a possibility to make window-items react on bindings
established via canvas->bind like the other (graphic)items do.
Do you have any idea why the ForwardEvent-Method does not work in this case? It
calls PassEvent, which is glue or Tk code (I'm not familiar with these internals)


> This strange behavior does not seem to be a speciality of Perl/Tk.
> Tcl/Tk shows the same problem:
>
> pack [canvas .can -width 300 -height 300]
> set item [.can create rectangle 5 5 100 100 -tags rectangle_item -fill red]
> entry .can.e -text "click here to test"
> set w_item [.can create window 200 200 -tags window_item -window .can.e]
> .can bind all <1> {puts "hallo %x %y"}
> #bind .can.e <1> { puts "window binding %x %y"; event generate .can <1> -x 200 -y 200 }
> bind .can.e <1> { puts "window binding %x %y"; after 200 { event generate .can <1> -x 200 -y 200 }}
>
> Maybe you can ask at comp.lang.tcl?


Yes, maybe I should, although unfortunately I don't know any tcl. :(

Thanks, Christoph

--

perl -e "print scalar reverse q/ed.enilno@ergn.l.hc/"
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com