469,647 Members | 1,811 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,647 developers. It's quick & easy.

Tkinter: How to get Label wraplength functionality in Text Box

I've tried quite a few things to get this correct but have hit a
couple of sticking points that I can't figure out. I need to ge the
Text box to function like the 'wraplength' option in a Label.

I've been able to adjust the height of the text by calculating the
number of lines needed to display the text. That's fairly simple. I
know the number of characters in the text and width of the box (which
is static). From that point I can calculate how many lines of display
is needed and resize it.

The problem arises when I use the 'wrap' option of the Text Box so the
words aren't chopped off. Once the wrapping is done there are dead
spaces left at the end of the lines which are ignored when the char
count is done. As a result sometimes the last line is not shown. I can
always just add +1 to the number, but then sometimes I get an empty
line. Space is at a premium in this app, so I have to cut everything
down to use only what's necessary.

So does anyone know how add in those extra spaces to get this to
adjust correctly? (Or if there is another way to get the Text Box to
automatically adjust it's size that I'm not aware of?)

Thanks
Oct 28 '08 #1
4 5041
On 10/28/08, Mudcat <mn******@gmail.comwrote:
I've tried quite a few things to get this correct but have hit a
couple of sticking points that I can't figure out. I need to ge the
Text box to function like the 'wraplength' option in a Label.

I've been able to adjust the height of the text by calculating the
number of lines needed to display the text. That's fairly simple. I
know the number of characters in the text and width of the box (which
is static). From that point I can calculate how many lines of display
is needed and resize it.

The problem arises when I use the 'wrap' option of the Text Box so the
words aren't chopped off. Once the wrapping is done there are dead
spaces left at the end of the lines which are ignored when the char
count is done. As a result sometimes the last line is not shown. I can
always just add +1 to the number, but then sometimes I get an empty
line. Space is at a premium in this app, so I have to cut everything
down to use only what's necessary.

So does anyone know how add in those extra spaces to get this to
adjust correctly? (Or if there is another way to get the Text Box to
automatically adjust it's size that I'm not aware of?)
Are you looking for something like the new "count" command for the
text widget in tk 8.5 ? "count" can count the number of logical lines
(irrespective of wrapping), display lines (counts one for each time a
line wraps) and some other things.

Thanks

--
http://mail.python.org/mailman/listinfo/python-list

--
-- Guilherme H. Polo Goncalves
Oct 28 '08 #2
Sounds like that would work really well. Problem is I can't get it to
work.

....
AttributeError: Text instance has no attribute 'count'
....

I think my usage is correct. I don't have any params at the moment,
but I was just checking the functionality.

numlines = widget.count()

According to the Tk 8.5 documentation it's used just like a normal
command.
WIDGET COMMAND
pathName count ?options? index1 index2
-chars
-displaychars
-displayindices
-displaylines
-indices
-lines
-xpixels
-ypixels
As for the environment, I thought I had everything set up correctly.
I've got the latest stable version of Python 2.6 (r26:66721, Oct 2
2008, 11:35:03). I'm implementing the TTK wrappers to access Tk 8.5.
Although when I check the wrapper I don't see any mods to the Text
Box. I also don't see this option in the Tkinter.py file.

Is there something else I need to add to access this new feature?
On Oct 28, 6:51*pm, "Guilherme Polo" <ggp...@gmail.comwrote:
>
Are you looking for something like the new "count" command for the
text widget in tk 8.5 ? "count" can count the number of logical lines
(irrespective of wrapping), display lines (counts one for each time a
line wraps) and some other things.
*Thanks
--
*http://mail.python.org/mailman/listinfo/python-list

--
-- Guilherme H. Polo Goncalves
Oct 29 '08 #3
On 10/30/08, Mudcat <mn******@gmail.comwrote:
I'm not sure why my tkinter would not be compiled against 8.5 since I
have the latest version. I assumed that Python 2.6 would have it
without requiring me to do an extra compile.
It is not really python's fault if tkinter is compiled against tcl/tk
8.5 or not. The windows installer for python 2.6 happens to include
tcl/tk 8.5 and tkinter compiled against them, but ubuntu for example
doesn't distribute tkinter compiled against tcl/tk 8.5 at the moment.
>
However I was able to get it working using the code you gave me.
Thanks for that. The only problem is that it seems to simply be
counting newlines (or number of \n). When I use the following:

numlines = widget.count("1.0", "end", "displaylines", "lines")
print "Number of lines is ", numlines

I get this:

Number of lines is (153, 1)
The first is the number of displaylines, the second is the number of lines.
>
So that's not actually the number of lines displayed in the box, just
the number of newline chars it finds.
Not really. displaylines returns the number of lines displayed in the
text widget, and lines returns the number of newlines found.
Note that it is important to call "count" only after the text widget
is being displayed, otherwise displaylines won't work correctly (not
with tk 8.5.3 at least).
I couldn't find anything in the
tk documentation that would give me any other options to count lines
differently, or number of lines displayed after wrapping.
Try this and check what you get:
import Tkinter

root = Tkinter.Tk()
text = Tkinter.Text()
text.pack()

def test(event):
print "displaylines:", text.count("1.0", "end", "displaylines")
print "lines:", text.count("1.0", "end", "lines")

text.insert("1.0", "a" * 81)
text.insert("2.0", "b\n")
text.bind('<Map>', test)

root.mainloop()
You should have 3 lines displayed but only 2 "real" lines.
--
-- Guilherme H. Polo Goncalves
Oct 30 '08 #4
Awesome...there it goes. I guess my main problem was trying to
evaluate the box before it had been displayed (or all the frame
propagations were finished). The key was getting the <Mapbinding in
there once I got the count functionality to work. After all
that...such a simple function:
def textBoxResize(self, event):
widget = event.widget
dispLines = widget.count("1.0", "end", "displaylines")
widget.config(height=dispLines)
Thanks for the help!
On Oct 30, 9:19*am, "Guilherme Polo" <ggp...@gmail.comwrote:
On 10/30/08, Mudcat <mnati...@gmail.comwrote:
I'm not sure why my tkinter would not be compiled against 8.5 since I
*have the latest version. I assumed that Python 2.6 would have it
*without requiring me to do an extra compile.

It is not really python's fault if tkinter is compiled against tcl/tk
8.5 or not. The windows installer for python 2.6 happens to include
tcl/tk 8.5 and tkinter compiled against them, but ubuntu for example
doesn't distribute tkinter compiled against tcl/tk 8.5 at the moment.
*However I was able to get it working using the code you gave me.
*Thanks for that. The only problem is that it seems to simply be
*counting newlines (or number of \n). When I use the following:
* * * * numlines = widget.count("1.0", "end", "displaylines","lines")
* * * * print "Number of lines is ", numlines
*I get this:
*Number of lines is *(153, 1)

The first is the number of displaylines, the second is the number of lines.
*So that's not actually the number of lines displayed in the box, just
*the number of newline chars it finds.

Not really. displaylines returns the number of lines displayed in the
text widget, and lines returns the number of newlines found.
Note that it is important to call "count" only after the text widget
is being displayed, otherwise displaylines won't work correctly (not
with tk 8.5.3 at least).
I couldn't find anything in the
*tk documentation that would give me any other options to count lines
*differently, or number of lines displayed after wrapping.

Try this and check what you get:

import Tkinter

root = Tkinter.Tk()
text = Tkinter.Text()
text.pack()

def test(event):
* * print "displaylines:", text.count("1.0", "end", "displaylines")
* * print "lines:", text.count("1.0", "end", "lines")

text.insert("1.0", "a" * 81)
text.insert("2.0", "b\n")
text.bind('<Map>', test)

root.mainloop()

You should have 3 lines displayed but only 2 "real" lines.

--
-- Guilherme H. Polo Goncalves
Oct 30 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by max(01)* | last post: by
5 posts views Thread by max(01)* | last post: by
5 posts views Thread by max(01)* | last post: by
1 post views Thread by vigacmoe | last post: by
4 posts views Thread by MartinRinehart | last post: by
3 posts views Thread by joshdw4 | last post: by
1 post views Thread by Dude | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.