Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

How do I count wrapped lines in TK.::Text?

by jeorgen (Pilgrim)
on Aug 19, 2002 at 22:48 UTC ( [id://191331]=perlquestion: print w/replies, xml ) Need Help??

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

Dear fellow Monks,

I'm trying to write a Tk UI where text widgets autoexpand to have the necessary height to show all text. I haven't been able to find any way of determining how many lines high the text widget needs to be to accomodate the contained text in full view.

Here is some code, modified from an example in the "Mastering Perl/Tk" book from O'Reilly, where I've been experimenting with the yview and index methods. Still that path will not shrink the text widget when text is short

use Tk; $mw= MainWindow->new; $mw->title('sadfa'); $f = $mw->Frame->pack(-side=>'bottom'); $f->Button(-text=>'Print',-command=>\&print_info)->pack(-side=>'left') +; $t=$mw->Scrolled("Text", -width=>40, -wrap=>'none')->pack(-expand=>1, +-fill=>'both'); @widget_list = (); $long_text = "text1 text1 text1 text1 text1 text1 text1 text1 text1 te +xt1 "; foreach ($long_text,"text2", "text3", "text4") { $w= $t->Text( -width=>20, -height=>2); $w->insert('end',$_); $t->windowCreate('end',-window=>$w); $t->insert('end', "\n"); push @widget_list, $w; } sub print_info { foreach my $text (@widget_list) { print join " ", $text->yview; print "\n"; my $index = $text->index('end'); print qq§ index : $index \n§; } print "----------\n"; } MainLoop;
/jeorgen

Replies are listed 'Best First'.
Re: How do I count wrapped lines in TK.::Text?
by graff (Chancellor) on Aug 20, 2002 at 01:59 UTC
    This is a bit confusing, because your code example does not seem to have much in common with your initial request, which was:

    I'm trying to write a Tk UI where text widgets autoexpand to have the necessary height to show all text.

    This would involve using the length of the string being displayed in order to do one of two things: assign initial "-width" and "-height" attributes when the text widget is created, or else use the widget's "configure()" method after it has been created. The former works if the string length is known before creating the widget; the latter if the string is created or changed after the widget is in place.

    But you don't seem to be using the length of the string to set the widget dimensions yet.

    I haven't been able to find any way of determining how many lines high the text widget needs to be to accomodate the contained text in full view.

    The easiest way (which can tend to make the text hard to read at runtime) is to set the text widget for character wrapping (as opposed to no-wrap or word-wrap), keep a fixed width for the widget (say, 40), and divide the string length by that width to decide how many lines are needed.

    I've added a little to your example to demonstrate using string length to configure widget dimensions. But I have to admit there are things I don't get, like why you have a set of smaller unscrolled text widgets in a bigger scrolled one, or how the "print_info" is expected to help things.

    use strict; use Tk; my $mw= MainWindow->new; $mw->title('vartext'); my $f = $mw->Frame->pack(-side=>'bottom'); $f->Button(-text=>'Print',-command=>\&print_info)->pack(-side=>'left') +; my $t=$mw->Scrolled("Text", -width=>40, -wrap=>'none')->pack(-expand=> +1, -fill=>'both'); my @widget_list = (); my @strings = (" a..5 a.10 a.15 a.20 a.25 a.30 a.35 a.40 a.45 a.50", " b..5 b.10 b.15 b.20 b.25 b.30 b.35 b.40", " c..5 c.10 c.15 c.20 c.25 c.30", " d..5 d.10 d.15 d.20", ); my $wdth = 20; foreach ( @strings ) { my $hght = int( length() / $wdth ); $hght++ if ( length() % $wdth ); my $w= $t->Text( -width=>20, -height=>$hght, -wrap=>'char'); $w->insert('end',$_); $t->windowCreate('end',-window=>$w); $t->insert('end', "\n"); push @widget_list, $w; } sub print_info { foreach my $text (@widget_list) { print join " ", $text->yview; print "\n"; my $index = $text->index('end'); print qq§ index : $index \n§; } print "----------\n"; } MainLoop;

    It would be a little trickier (but easier for a user to read) if you used word wrapping instead of character wrapping: you may have to replicate the widget's wrapping behavior to figure out how many display lines will be needed -- or just "pre-wrap" the lines yourself (and you can find a lot of useful ideas for word-boundary-based line wrapping by searching this site).

      Thanks for your reply, and your code graff!

      All I really need is a function that gives me the number of display  lines of the (proportional font) text in the widget if the widget had enough height, not logical lines if the widget had infinite width. I suspect there might be something like that in the layout functions of Tk, but alas, I do not understand things that deep down as yet.

      graff writes:
      The easiest way (which can tend to make the text hard to read at runtime) is to set the text widget for character wrapping (as opposed to no-wrap or word-wrap), keep a fixed width for the widget (say, 40), and divide the string length by that width to decide how many lines are needed. 

      I want to be able to use a proportional font, you see... I should have written that. And I want to use word wrapping. It was very late here (CET) when I posted so I did not  describe the problem concisely enough.

      I've added a little to your example to demonstrate using string length to configure widget dimensions. But I have to admit there are things I don't get, like why you have a set of smaller unscrolled text widgets in a bigger scrolled one, or how the "print_info" is expected to help things.

      Each widget will hold a paragraph an be editable remotely by a another user. Print info is there just to demonstrate that the yscroll would be perfectly usable for expandning the window to the right size (by dividing the current height of the widget with the yscroll value, and this should work with proportional text as well), but not to shrink it accordingly. The index value demonstrates that the number of lines counted are logical lines, not display lines. Again, some better labelling and some number crunching in that fucntion would make that less cryptic.

       

      /jeorgen

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2024-04-19 22:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found