Reputation:
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
Upvotes: 4
Views: 3623
Reputation: 19664
Here's how to dynamically change canvas text size and width in Tkinter:
"""Dynamic Tkinter canvas text size and wrap.
By Cees Timmerman, 2024-04-10."""
from tkinter import Canvas, NW, Tk
root = Tk()
root.geometry("200x200")
root.update()
canvas = Canvas()
canvas.place(x=0, y=0, relwidth=1, relheight=1)
FONT_SIZE: int = 10
text_h = canvas.create_text(
20,
30,
anchor=NW,
font=("Purisa", FONT_SIZE),
text="Most relationships seem so transitory",
width=root.winfo_width(),
)
def animate(font_size):
"""Grows and wraps canvas text in Tkinter."""
if font_size < 20:
font_size += 1
else:
font_size = FONT_SIZE
canvas.itemconfig(text_h, font=("Purisa", font_size), width=root.winfo_width())
root.after(1000, animate, font_size)
animate(FONT_SIZE)
root.mainloop()
Upvotes: 0
Reputation: 6179
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.
Upvotes: 2
Reputation: 7423
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.
Upvotes: 1