The traditional first program, in the form it takes in Python 3.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Hello, world")
label.pack()
root.mainloop()
Four things happen.
tk.Tk() starts the toolkit and creates the main window.root as its first argument. Every widget takes its parent that way, which is how the widget tree is built.pack() hands the label to a geometry manager. Until you do that, the widget exists but is not on screen. This surprises everybody once.mainloop() gives control to Tk, which waits for events and returns only when the window closes.Tkinter with a capital T. In Python 3 it is tkinter. That rename is why so many old examples fail on the first line.Anything beyond a single window is easier as a class, because the widgets and the methods that respond to them then live together.
import tkinter as tk
from tkinter import ttk
class Application(ttk.Frame):
def __init__(self, parent):
super().__init__(parent, padding=12)
self.grid(sticky="nsew")
self.build()
def build(self):
self.message = tk.StringVar(value="Hello, world")
ttk.Label(self, textvariable=self.message).grid(row=0, column=0, pady=6)
ttk.Button(self, text="Change", command=self.change).grid(row=1, column=0)
ttk.Button(self, text="Quit", command=self.winfo_toplevel().destroy).grid(row=2, column=0, pady=6)
def change(self):
self.message.set("Hello again")
root = tk.Tk()
root.title("Example")
Application(root)
root.mainloop()
Three habits worth picking up from this.
ttk.Frame rather than Tk. The application is then a component you could drop into another window.StringVar rather than reading and writing widget text. The label updates itself when the variable changes.command, not a call. command=self.change is right, command=self.change() runs it once at startup and passes the result.ttk.Button(self, text="Red", command=lambda: self.pick("red")).grid(row=3, column=0)
Careful inside loops. A lambda that closes over the loop variable sees its final value, so bind it as a default argument instead:
for colour in ("red", "green", "blue"):
ttk.Button(self, text=colour, command=lambda c=colour: self.pick(c)).grid()