> From: Michael Carman 

> One of the users of my Tkx::ROText widget ran into a problem 
> binding it.
> 
>     use Tkx;
>     use Tkx::ROText;
> 
>     my $mw   = Tkx::widget->new(".");
>     my $text = $mw->new_tkx_ROText(-state=>'normal');
>     $text->g_pack();
> 
>     Tkx::bind($text, '<Enter>',  sub { warn "<Enter>\n"  });
>     Tkx::bind($text, '<Return>', sub { warn "<Return>\n" });
> 
>     Tkx::MainLoop();
> 
> The <Enter> binding works, but the <Return> binding doesn't. The
> problem is that Tkx::ROText is really a frame that embeds a text
> widget. IIRC the reason for this was that only frames support the
> -class option in their constructor and therefore all Tkx mega-widgets
> should be frame-based. (Decided via a discussion on this list some
> time ago.) It's not really surprising that the <Return> binding
> doesn't work because it's attached to the frame but the event happens
> inside the text widget -- the frame never sees it.

Indeed, the problem of delegating events exists.

Tcl/Tk has several megawidgets frameworks, which deal with the problem
this or that way.
I do not know how Tkx handles them, or rather reimplements them
(or rather do not reimplement them)

In Tcl::Tk, "rotext" is implemented via "snit" framework, so following
code works:

use Tcl::Tk;

my $int = new Tcl::Tk;
my $text = $int->mainwindow->ROText->pack;
$text->insert('end', join "\n", 'a'..'zzz');

$int->bind($text, '<Enter>',  sub { warn "<Enter>\n"  });
$int->bind($text, '<Return>', sub { warn "<Return>\n" });

$int->MainLoop;

However "scrolled" ROText suffers same problem as yours, so
needs "Subwidget" method:

use Tcl::Tk;

my $int = new Tcl::Tk;
my $text = $int->mainwindow->Scrolled('ROText')->pack;
$text->insert('end', join "\n", 'a'..'zzz');

$int->bind($text, '<Enter>',  sub { warn "<Enter>\n"  });
$int->bind($text->Scrolled, '<Return>', sub { warn "<Return>\n" });

$int->MainLoop;

> 
> The work-around is to bind directly to the inner text widget.
> 
>     Tkx::bind($text . '.text', '<Return>', sub { warn "<Return>\n" });
> 
> I have a few problems with this. First, the inner text widget isn't
> publicized, so doing it violates encapsulation. (Tangent: Tkx doesn't
> provide an equivalent to Perl/Tk's Advertise() and Subwidget()
> methods. The best I could do is publically document it.) Second,
> binding to the sub-widget forces you to use Tkx::bind() instead of
> $text->g_bind(). The forms should be equivalent. Finally, I don't want
> users to have to do anything special. Binding should "just work"
> without surprises.
> 
> Is there a way to make this "just work" in Tkx? 

I suppose Tkx developers should adopt some well-tested Tcl/Tk megawidget
framework. to support megawidgets.

This is my *humble* opinion on the matter, as I do not know Tkx deeply.

But I very much hope that someone with better experience in Tkx will advice 
better.

Regards,
Vadim.

Reply via email to