Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic sizing Tkinter canvas text

Tags:

python

tkinter

I am talking specific to python Tkinter, I have text along with a button in-lined and I am using pixel coordinates. Now my text string is changing dynamically, but if the text string is long then it overflows.

So I want if there any way if I can change the coordinates based on text length

For example:

canvas.create_text(20, 30, anchor=W, font="Purisa",
    text="Most relationships seem so transitory")

If I use something like this

canvas.create_text(20+len(text), 30, anchor=W, font="Purisa",
    text="Most relationships seem so transitory")

I am very new to tkinter and got a code to debug which is very tight, so I cannot change it dynamically in first place


2 Answers

You can calculate the coordinates based on the size of the text, but you need to find out the size of the text in the given font in pixels. This can be done in Tkinter by first using a scratch canvas and the bbox method. Create the text item and capture the id, then use the bbox method to get its size.

scratch = Canvas()
id = scratch.create_text((0, 0), text=text, <options>)
size = scratch.bbox(id)
# size is a tuple: (x1, y1, x2, y2)
# since x1 and y1 will be 0, x2 and y2 give the string width and height

Then you can calculate your x and y coordinates based on the results and draw it on your actual canvas. There is likely also a more efficient way to do this, but I don't know of it yet.

Or maybe you just want the x position to change based on the text size, in other words, making it right justified. In Tkinter this is most easily done by using the "anchor=E" option and giving the right edge of the text area for the x coordinate:

canvas.create_text(ButtonX - 10, 30, anchor=E, ...)

You can also use "width=200" for example to wrap the text in a 200 pixel wide box, in addition to anchor and any other options.

like image 103
Todd Avatar answered Oct 26 '25 11:10

Todd


You can pass the "width" in create_text to avoid overflow.

width=Maximum line length. Lines longer than this value are wrapped. Default is 0 (no wrapping).

so it will be something like this

canvas.create_text(20, 30, anchor=W, font="Purisa",
     text="Most relationships seem so transitory", width=0)

you can calculate the width based on the text size or make it fix, then if it is longer than it will be wrapped and there won't be any overflow.

like image 41
DevC Avatar answered Oct 26 '25 09:10

DevC