GUI Programming
GUI questions target Tkinter's structure: which geometry manager takes which options, how callbacks receive arguments, and what Entry.get() actually returns. Most stems show a small window built from a few lines and ask for the output or the exception, so trace the widget tree and the event loop rather than guessing.
Structure and layout
- One
tk.Tk()root per process; additional windows aretk.Toplevel. Withoutroot.mainloop()the window never processes events. pack(side=..., fill=..., expand=True)stacks widgets;grid(row=, column=, sticky='nsew', padx=, pady=)places them on a grid;placeuses absolute coordinates.- Never mix
packandgridinside the same container. Grid cells only grow if you setroot.columnconfigure(0, weight=1).
Widgets and variables
Label,Button,Entry(single-line,.get()always returnsstr),Text(multi-line, indices such as'1.0'and'end'),Listbox,Canvas,Frame;tkinter.ttksupplies themed variants.CheckbuttonandRadiobuttonlink toIntVar/StringVar; create one withvar = tk.StringVar(value='x')and read it with.get().command=handlerreceives the function object and passes no arguments;bind('<Return>', handler)passes an event exposing.widget,.x,.y,.keysym.
Worked example
def convert(*_):
try:
out.set(f'{float(celsius.get()) * 9 / 5 + 32:.1f}')
except ValueError:
out.set('?')
celsius = tk.StringVar()
out = tk.StringVar()
tk.Entry(root, textvariable=celsius).grid(row=0, column=0)
tk.Button(root, text='Convert', command=convert).grid(row=0, column=1)
Reasoning: command=convert hands over the callable, whereas command=convert() would run it once at build time and pass None back. The *_ parameter lets the same function serve a <Return> binding, which supplies an event object. State lives in the variables, so the callback needs no widget reference.
Traps
- An uncaught
ValueErrorfromfloat('')is printed to stderr while the GUI stays unchanged, so guard every conversion. - Creating a second
Tk()inside a callback spins up a second interpreter and behaves unpredictably; useToplevel.