1

I discovered a simple way to make an auto-resizing Tkinter Entry. As you type or delete characters, it grows or shrinks to fit its contents exactly. There are other ways to approximate this effect, but not as simple, and this one makes the Entry fit its contents perfectly with very little code.

The only thing I don't like about it is that it has no width unless given initial width with invisible content. The place() geometry manager has a width option but it's a fixed width, not a minimum width. The Label's width option also gives the Entry a fixed width, and the Entry's width option has no effect in this code. If someone can demonstrate a better way to give this Entry an initial minimum size instead of inserting invisible content, I'd like to improve it in that way. Thanks.

EDIT: This code has an additional related defect I didn't notice when I posted the question. When you start typing into the Entry, the first character you type shifts to the left and doesn't show. I didn't notice this before because I was testing it by entering a string like "kkkkkkkkkkkkkkkk" and didn't notice the first "k" was not visible. But if you type "enforce", the initial "e" doesn't show up. So in addition to needing an initial width so the empty Entry can be seen, it needs to retain that width until the first character has been typed. I'm not changing the question, just making note of this additional defect, because I'd said above that the Entry fit its contents perfectly and it doesn't.

import tkinter as tk

class EntryExpanding(tk.Entry): def init(self, master, *args, **kwargs): tk.Entry.init(self, master, *args, **kwargs)

    hmmmm = tk.StringVar()

    self.sizer = tk.Label(master, textvariable=hmmmm)

    expansive = tk.Entry(self.sizer, textvariable=hmmmm)
    expansive.place(x=0, y=0, anchor='nw', relwidth=1.0, relheight=1.0)

    expansive.insert(0, '              ')

    self.grid = self.sizer.grid

if name == 'main':

root = tk.Tk()
root.geometry('+700+200')

xpando = EntryExpanding(root)
xpando.grid()

ordinary = tk.Entry(root)
ordinary.grid()

root.mainloop()
Luther
  • 514
  • 4
  • 17

0 Answers0