> 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.