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

How do trap and respond to a resize event for a widget in pTk?

For example, I'd like to be able to adjust the wraplength for a label as the size of the window changes. Is there an event I can bind to that will let me configure my Label as needed?

The code below demonstrates a Label widget that does not 'reflow' when the window is resized.

use strict; use warnings; use Tk; my $mw = MainWindow->new(); my $long_text = <<EOT; Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque + dictum tempor augue. Sed id pede. Suspendisse a erat a risus tincidu +nt rhoncus. Integer eget risus. Nulla nunc odio, viverra eget, consec +tetuer non, mollis at, felis. In hac habitasse platea dictumst. Nulla + accumsan volutpat eros. Vivamus convallis, eros ut convallis facilis +is, justo ipsum convallis orci, vehicula laoreet purus eros eget ante +. In tempor. Proin varius placerat nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, pe +r inceptos hymenaeos. Aenean pretium augue ac nulla. Praesent ante ri +sus, iaculis et, malesuada a, luctus in, orci. Sed erat odio, auctor +sed, molestie vel, volutpat at, elit. Phasellus fermentum ultricies e +st. Aenean interdum elit sit amet est. Donec luctus lacus a turpis. S +ed et risus. Fusce metus. Pellentesque lorem dolor, volutpat in, cong +ue id, luctus et, magna. Nullam congue sagittis orci. Pellentesque ne +c metus. Nulla nulla. EOT # how can I force wraplegth to adjust as the main window (or container + frame) is resized? $mw->Label( -text => $long_text, -wraplength => 250, )->pack( -fill => 'both', -expand => 1, ); MainLoop;


TGI says moo

Replies are listed 'Best First'.
Re: Handling resizing in pTk
by liverpole (Monsignor) on Oct 09, 2007 at 18:05 UTC
    Hi TGI,

    If you want wrapping done automatically for you, how about using a Text widget instead?:

    my $textbox = $mw->Text( -wrap => 'word', )->pack( -fill => 'both', -expand => 1, ); $mw->after(100 => sub { initialize() }); MainLoop; sub initialize { $textbox->insert("1.0", $long_text); }

    Then you can choose between the following types of wrap:

    -wrap => 'none' .... Don't do any wrapping at all -wrap => 'char' .... Wrap between characters -wrap => 'word' .... Wrap between words

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      Unfortunately, I'm stuck with a label, unless I want to dig in to a bunch of inherited code.

      In general, I aggree that a Text, or more specifically, an ROText would be pretty good for this sort of thing.


      TGI says moo

Re: Handling resizing in pTk
by TGI (Parson) on Oct 09, 2007 at 18:31 UTC

    I should have waited a bit longer before posting. I found the answer.

    The event to bind is Configure.

    Just bind a callback to a Configure event on your widget, and you can reconfigure as you please.

    What surprised me was that I could call the widget's configure method in the ConfigureConfigure callback without creating infinite recursion.

    The code below shows the technique.

    use strict; use warnings; use Tk; my $mw = MainWindow->new(); my $long_text = <<EOT; Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque + dictum tempor augue. Sed id pede. Suspendisse a erat a risus tincidu +nt rhoncus. Integer eget risus. Nulla nunc odio, viverra eget, consec +tetuer non, mollis at, felis. In hac habitasse platea dictumst. Nulla + accumsan volutpat eros. Vivamus convallis, eros ut convallis facilis +is, justo ipsum convallis orci, vehicula laoreet purus eros eget ante +. In tempor. Proin varius placerat nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, pe +r inceptos hymenaeos. Aenean pretium augue ac nulla. Praesent ante ri +sus, iaculis et, malesuada a, luctus in, orci. Sed erat odio, auctor +sed, molestie vel, volutpat at, elit. Phasellus fermentum ultricies e +st. Aenean interdum elit sit amet est. Donec luctus lacus a turpis. S +ed et risus. Fusce metus. Pellentesque lorem dolor, volutpat in, cong +ue id, luctus et, magna. Nullam congue sagittis orci. Pellentesque ne +c metus. Nulla nulla. EOT my $l = $mw->Label( -text => $long_text, -wraplength => 250, )->pack( -fill => 'both', -expand => 1, ); $l->bind( '<Configure>', => [ \&ResizeMe, Ev('w') ] ); sub ResizeMe { my $l = shift; my $w = shift; # Amazingly, this does not lead to infinite recursion. $l->configure( -wraplength => $w ); } MainLoop;

    Update: I forgot to mention, that I figured this out by looking at the Tk::bind POD. The section called "BINDING CALLBACKS AND SUBSTITUTIONS" includes an entry for the 'w' character which returns a width for an event. The event list includes Configure, as does the h/height entry. So, I figured, maybe Configure events are generated when a widget is resized. I tried a quick binding and it worked.


    TGI says moo