For a game I'm making, I need the user to input data, and I want to call a method that adds a little Entry box to my GUI (to get the user's name), but when I try to do so the Entry widget basically masks all other things and makes them disappear. Any ideas on why this happens or how to fix? Here's an example of the problematic code:
root = tkinter.Tk()
root.title('2048')
width = 500
height = 800
root.geometry('%sx%s' % (width, height))
canvas = tkinter.Canvas(root, width=width, height=height, highlightthickness=0)
canvas.pack()
r = canvas.create_rectangle(0, 0, 50, 50)
canvas.move(r, 50, 50)
def keyed(event):
e = tkinter.Entry(canvas)
e.pack()
canvas.bind('<Key>', keyed)
canvas.focus_set()
root.mainloop()
This is the standard behavior when you use pack
or grid
- widgets will grow or shrink to fit their contents. when you pack an entry in the canvas, the canvas will shrink or grow to fit the canvas. This is called geometry propagation.
There are at least three ways to solve this. The first is to not put the widget inside the canvas. Instead, put it above, below, or to one side (eg: e = tkinter.Entry(root)
)
Another solution is to not use pack
(or grid
). Instead, use the canvas create_window
method to make the entry widget a first class canvas object. You will have to decide where to put it since the create_window
method requires an x/y coordinate.
A third option is to contiue to use pack
but turn geometry propagation off. Personally I think this feature should almost never be used. The fact that widgets grow or shrink is a feature rather than a bug, and it's a feature that makes it easier to create responsive user interfaces.
To turn geometry propagation off for the canvas you can call canvas.pack_propagate(False)
if you continue to use pack
, or canvas.grid_propagate(False)
if you switch to using grid inside the canvas.