Repository: roseman/tkdocs Branch: master Commit: 1a53c4498e7b Files: 25 Total size: 23.3 KB Directory structure: gitextract_hu22vnbl/ ├── README.md ├── bindings.py ├── contextmenu.py ├── country.py ├── dialog.py ├── f2m.py ├── f2mo.py ├── gridexample1.py ├── gridexample2.py ├── hello.py ├── logwindow.py ├── longrunning.py ├── menu.py ├── numvalidate.py ├── recentfiles.py ├── scale.py ├── scrollbar.py ├── scrolledtext.py ├── sketch1.py ├── sketch2.py ├── sketch3.py ├── sketch4.py ├── sketcho.py ├── stackorder.py └── validate.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ # TkDocs Examples This repository contains example Tkinter code that appears in the book *Modern Tkinter* as well as the tutorial at https://tkdocs.com. ================================================ FILE: bindings.py ================================================ from tkinter import * from tkinter import ttk root = Tk() l =ttk.Label(root, text="Starting...") l.grid() l.bind('', lambda e: l.configure(text='Moved mouse inside')) l.bind('', lambda e: l.configure(text='Moved mouse outside')) l.bind('<1>', lambda e: l.configure(text='Clicked left mouse button')) l.bind('', lambda e: l.configure(text='Double clicked')) l.bind('', lambda e: l.configure(text=f'right button drag to {e.x},{e.y}')) root.mainloop() ================================================ FILE: contextmenu.py ================================================ from tkinter import * root = Tk() if (root.tk.call('tk', 'windowingsystem')=='aqua'): root.event_add('<>', '') menu = Menu(root) for i in ('One', 'Two', 'Three'): menu.add_command(label=i) root.bind('<>', lambda e: menu.post(e.x_root, e.y_root)) root.mainloop() ================================================ FILE: country.py ================================================ from tkinter import * from tkinter import ttk root = Tk() # Initialize our country "databases": # - the list of country codes (a subset anyway) # - parallel list of country names, same order as the country codes # - a hash table mapping country code to population countrycodes = ('ar', 'au', 'be', 'br', 'ca', 'cn', 'dk', 'fi', 'fr', 'gr', 'in', 'it', 'jp', 'mx', 'nl', 'no', 'es', 'se', 'ch') countrynames = ('Argentina', 'Australia', 'Belgium', 'Brazil', 'Canada', 'China', 'Denmark', \ 'Finland', 'France', 'Greece', 'India', 'Italy', 'Japan', 'Mexico', 'Netherlands', 'Norway', 'Spain', \ 'Sweden', 'Switzerland') cnames = StringVar(value=countrynames) populations = {'ar':41000000, 'au':21179211, 'be':10584534, 'br':185971537, \ 'ca':33148682, 'cn':1323128240, 'dk':5457415, 'fi':5302000, 'fr':64102140, 'gr':11147000, \ 'in':1131043000, 'it':59206382, 'jp':127718000, 'mx':106535000, 'nl':16402414, \ 'no':4738085, 'es':45116894, 'se':9174082, 'ch':7508700} # Names of the gifts we can send gifts = { 'card':'Greeting card', 'flowers':'Flowers', 'nastygram':'Nastygram'} # State variables gift = StringVar() sentmsg = StringVar() statusmsg = StringVar() # Called when the selection in the listbox changes; figure out # which country is currently selected, and then lookup its country # code, and from that, its population. Update the status message # with the new population. As well, clear the message about the # gift being sent, so it doesn't stick around after we start doing # other things. def showPopulation(*args): idxs = lbox.curselection() if len(idxs)==1: idx = int(idxs[0]) code = countrycodes[idx] name = countrynames[idx] popn = populations[code] statusmsg.set("The population of %s (%s) is %d" % (name, code, popn)) sentmsg.set('') # Called when the user double clicks an item in the listbox, presses # the "Send Gift" button, or presses the Return key. In case the selected # item is scrolled out of view, make sure it is visible. # # Figure out which country is selected, which gift is selected with the # radiobuttons, "send the gift", and provide feedback that it was sent. def sendGift(*args): idxs = lbox.curselection() if len(idxs)==1: idx = int(idxs[0]) lbox.see(idx) name = countrynames[idx] # Gift sending left as an exercise to the reader sentmsg.set("Sent %s to leader of %s" % (gifts[gift.get()], name)) # Create and grid the outer content frame c = ttk.Frame(root, padding=(5, 5, 12, 0)) c.grid(column=0, row=0, sticky=(N,W,E,S)) root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(0,weight=1) # Create the different widgets; note the variables that many # of them are bound to, as well as the button callback. # We're using the StringVar() 'cnames', constructed from 'countrynames' lbox = Listbox(c, listvariable=cnames, height=5) lbl = ttk.Label(c, text="Send to country's leader:") g1 = ttk.Radiobutton(c, text=gifts['card'], variable=gift, value='card') g2 = ttk.Radiobutton(c, text=gifts['flowers'], variable=gift, value='flowers') g3 = ttk.Radiobutton(c, text=gifts['nastygram'], variable=gift, value='nastygram') send = ttk.Button(c, text='Send Gift', command=sendGift, default='active') sentlbl = ttk.Label(c, textvariable=sentmsg, anchor='center') status = ttk.Label(c, textvariable=statusmsg, anchor=W) # Grid all the widgets lbox.grid(column=0, row=0, rowspan=6, sticky=(N,S,E,W)) lbl.grid(column=1, row=0, padx=10, pady=5) g1.grid(column=1, row=1, sticky=W, padx=20) g2.grid(column=1, row=2, sticky=W, padx=20) g3.grid(column=1, row=3, sticky=W, padx=20) send.grid(column=2, row=4, sticky=E) sentlbl.grid(column=1, row=5, columnspan=2, sticky=N, pady=5, padx=5) status.grid(column=0, row=6, columnspan=2, sticky=(W,E)) c.grid_columnconfigure(0, weight=1) c.grid_rowconfigure(5, weight=1) # Set event bindings for when the selection in the listbox changes, # when the user double clicks the list, and when they hit the Return key lbox.bind('<>', showPopulation) lbox.bind('', sendGift) root.bind('', sendGift) # Colorize alternating lines of the listbox for i in range(0,len(countrynames),2): lbox.itemconfigure(i, background='#f0f0ff') # Set the starting state of the interface, including selecting the # default gift to send, and clearing the messages. Select the first # country in the list; because the <<ListboxSelect>> event is only # fired when users makes a change, we explicitly call showPopulation. gift.set('card') sentmsg.set('') statusmsg.set('') lbox.selection_set(0) showPopulation() root.mainloop() ================================================ FILE: dialog.py ================================================ from tkinter import * from tkinter import ttk root = Tk() ttk.Entry(root).grid() # something to interact with def dismiss (): dlg.grab_release() dlg.destroy() dlg = Toplevel(root) ttk.Button(dlg, text="Done", command=dismiss).grid() dlg.protocol("WM_DELETE_WINDOW", dismiss) # intercept close button dlg.transient(root) # dialog window is related to main dlg.wait_visibility() # can't grab until window appears, so we wait dlg.grab_set() # ensure all input goes to our window dlg.wait_window() # block until window is destroyed root.mainloop() ================================================ FILE: f2m.py ================================================ from tkinter import * from tkinter import ttk def calculate(*args): try: value = float(feet.get()) meters.set(round(0.3048 * value, 4)) except ValueError: pass root = Tk() root.title("Feet to Meters") mainframe = ttk.Frame(root, padding=(3, 3, 12, 12)) mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) feet = StringVar() feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet) feet_entry.grid(column=2, row=1, sticky=(W, E)) meters = StringVar() ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E)) ttk.Button(mainframe, text="Calculate", command=calculate).grid(column=3, row=3, sticky=W) ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W) ttk.Label(mainframe, text="is equivalent to").grid(column=1, row=2, sticky=E) ttk.Label(mainframe, text="meters").grid(column=3, row=2, sticky=W) root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) mainframe.columnconfigure(2, weight=1) for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) feet_entry.focus() root.bind("", calculate) root.mainloop() ================================================ FILE: f2mo.py ================================================ from tkinter import * from tkinter import ttk class FeetToMeters: def __init__(self, root): root.title("Feet to Meters") mainframe = ttk.Frame(root, padding=(3, 3, 12, 12)) mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) self.feet = StringVar() feet_entry = ttk.Entry(mainframe, width=7, textvariable=self.feet) feet_entry.grid(column=2, row=1, sticky=(W, E)) self.meters = StringVar() ttk.Label(mainframe, textvariable=self.meters).grid(column=2, row=2, sticky=(W, E)) ttk.Button(mainframe, text="Calculate", command=self.calculate).grid(column=3, row=3, sticky=W) ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W) ttk.Label(mainframe, text="is equivalent to").grid(column=1, row=2, sticky=E) ttk.Label(mainframe, text="meters").grid(column=3, row=2, sticky=W) root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) mainframe.columnconfigure(2, weight=1) for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) feet_entry.focus() root.bind("", self.calculate) def calculate(self, *args): try: value = float(self.feet.get()) self.meters.set(round(0.3048 * value, 4)) except ValueError: pass root = Tk() FeetToMeters(root) root.mainloop() ================================================ FILE: gridexample1.py ================================================ from tkinter import * from tkinter import ttk root = Tk() content = ttk.Frame(root) frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) namelbl = ttk.Label(content, text="Name") name = ttk.Entry(content) onevar = BooleanVar() twovar = BooleanVar() threevar = BooleanVar() onevar.set(True) twovar.set(False) threevar.set(True) one = ttk.Checkbutton(content, text="One", variable=onevar, onvalue=True) two = ttk.Checkbutton(content, text="Two", variable=twovar, onvalue=True) three = ttk.Checkbutton(content, text="Three", variable=threevar, onvalue=True) ok = ttk.Button(content, text="Okay") cancel = ttk.Button(content, text="Cancel") content.grid(column=0, row=0) frame.grid(column=0, row=0, columnspan=3, rowspan=2) namelbl.grid(column=3, row=0, columnspan=2) name.grid(column=3, row=1, columnspan=2) one.grid(column=0, row=5) two.grid(column=1, row=5) three.grid(column=2, row=5) ok.grid(column=3, row=5) cancel.grid(column=4, row=5) root.mainloop() ================================================ FILE: gridexample2.py ================================================ from tkinter import * from tkinter import ttk root = Tk() content = ttk.Frame(root, padding=(3,3,12,12)) frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) namelbl = ttk.Label(content, text="Name") name = ttk.Entry(content) onevar = BooleanVar() twovar = BooleanVar() threevar = BooleanVar() onevar.set(True) twovar.set(False) threevar.set(True) one = ttk.Checkbutton(content, text="One", variable=onevar, onvalue=True) two = ttk.Checkbutton(content, text="Two", variable=twovar, onvalue=True) three = ttk.Checkbutton(content, text="Three", variable=threevar, onvalue=True) ok = ttk.Button(content, text="Okay") cancel = ttk.Button(content, text="Cancel") content.grid(column=0, row=0, sticky=(N, S, E, W)) frame.grid(column=0, row=0, columnspan=3, rowspan=2, sticky=(N, S, E, W)) namelbl.grid(column=3, row=0, columnspan=2, sticky=(N, W), padx=5) name.grid(column=3, row=1, columnspan=2, sticky=(N, E, W), pady=5, padx=5) one.grid(column=0, row=5) two.grid(column=1, row=5) three.grid(column=2, row=5) ok.grid(column=3, row=5) cancel.grid(column=4, row=5) root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) content.columnconfigure(0, weight=3) content.columnconfigure(1, weight=3) content.columnconfigure(2, weight=3) content.columnconfigure(3, weight=1) content.columnconfigure(4, weight=1) content.rowconfigure(1, weight=1) root.mainloop() ================================================ FILE: hello.py ================================================ from tkinter import * from tkinter import ttk root = Tk() ttk.Button(root, text="Hello World").grid() root.mainloop() ================================================ FILE: logwindow.py ================================================ from tkinter import * from tkinter import ttk from datetime import datetime root = Tk() log = Text(root, state='disabled', width=80, height=24, wrap='none') log.grid() def writeToLog(msg): numlines = int(log.index('end - 1 line').split('.')[0]) log['state'] = 'normal' if numlines == 24: log.delete(1.0, 2.0) if log.index('end-1c')!='1.0': log.insert('end', '\n') log.insert('end', msg) log['state'] = 'disabled' def writemsg(): writeToLog(str(datetime.now())+": all is well") root.after(200, writemsg) root.after(200, writemsg) root.mainloop() ================================================ FILE: longrunning.py ================================================ from tkinter import * from tkinter import ttk root = Tk() def start(): b.configure(text='Stop', command=stop) l['text'] = 'Working...' global interrupt; interrupt = False root.after(1, step) def stop(): global interrupt; interrupt = True def step(count=0): p['value'] = count if interrupt: result(None) return root.after(100) # next step in our operation; don't take too long! if count == 20: # done! result(42) return root.after(1, lambda: step(count+1)) def result(answer): p['value'] = 0 b.configure(text='Start', command=start) l['text'] = "Answer: " + str(answer) if answer else "No Answer" f = ttk.Frame(root); f.grid() b = ttk.Button(f, text="Start!", command=start); b.grid(column=1, row=0, padx=5, pady=5) l = ttk.Label(f, text="No Answer"); l.grid(column=0, row=0, padx=5, pady=5) p = ttk.Progressbar(f, orient="horizontal", mode="determinate", maximum=20); p.grid(column=0, row=1, padx=5, pady=5) root.mainloop() ================================================ FILE: menu.py ================================================ from tkinter import * from tkinter import ttk, messagebox root = Tk() ttk.Entry(root).grid() m = Menu(root) m_edit = Menu(m) m.add_cascade(menu=m_edit, label="Edit") m_edit.add_command(label="Paste", command=lambda: root.focus_get().event_generate("<>")) m_edit.add_command(label="Find...", command=lambda: root.event_generate("<>")) root['menu'] = m def launchFindDialog(*args): messagebox.showinfo(message="I hope you find what you're looking for!") root.bind("<>", launchFindDialog) root.mainloop() ================================================ FILE: numvalidate.py ================================================ from tkinter import * from tkinter import ttk root=Tk() import re def check_num(newval): return re.match('^[0-9]*$', newval) is not None and len(newval) <= 5 check_num_wrapper = (root.register(check_num), '%P') num = StringVar() e = ttk.Entry(root, textvariable=num, validate='key', validatecommand=check_num_wrapper) e.grid(column=0, row=0, sticky='we') root.mainloop() ================================================ FILE: recentfiles.py ================================================ from tkinter import * from tkinter import ttk import glob import os import os.path root=Tk() def openFile(f): print(f) recent_files = glob.glob(os.getcwd()+'/*.py') menubar = Menu(root) root['menu'] = menubar menu_file = Menu(menubar) menu_edit = Menu(menubar) menubar.add_cascade(menu=menu_file, label='File') menubar.add_cascade(menu=menu_edit, label='Edit') menu_recent = Menu(menu_file) menu_file.add_cascade(menu=menu_recent, label='Open Recent') for f in recent_files: menu_recent.add_command(label=os.path.basename(f), command=lambda: openFile(f)) root.mainloop() ================================================ FILE: scale.py ================================================ from tkinter import * from tkinter import ttk root=Tk() # label tied to the same variable as the scale, so auto-updates num = StringVar() ttk.Label(root, textvariable=num).grid(column=0, row=0, sticky='we') # label that we'll manually update via the scale's command callback manual = ttk.Label(root) manual.grid(column=0, row=1, sticky='we') def update_lbl(val): manual['text'] = "Scale at " + val scale = ttk.Scale(root, orient='horizontal', length=200, from_=1.0, to=100.0, variable=num, command=update_lbl) scale.grid(column=0, row=2, sticky='we') scale.set(20) root.mainloop() ================================================ FILE: scrollbar.py ================================================ from tkinter import * from tkinter import ttk root = Tk() l = Listbox(root, height=5) l.grid(column=0, row=0, sticky=(N,W,E,S)) s = ttk.Scrollbar(root, orient=VERTICAL, command=l.yview) s.grid(column=1, row=0, sticky=(N,S)) l['yscrollcommand'] = s.set ttk.Label(root, text="Status message here", anchor=(W)).grid(column=0, columnspan=2, row=1, sticky=(W,E)) root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(0, weight=1) for i in range(1,101): l.insert('end', 'Line %d of 100' % i) root.mainloop() ================================================ FILE: scrolledtext.py ================================================ from tkinter import * from tkinter import ttk root=Tk() t = Text(root, width = 40, height = 5, wrap = "none") ys = ttk.Scrollbar(root, orient = 'vertical', command = t.yview) xs = ttk.Scrollbar(root, orient = 'horizontal', command = t.xview) t['yscrollcommand'] = ys.set t['xscrollcommand'] = xs.set t.insert('end', "Lorem ipsum...\n...\n... dolor sit amet, consectetur adipiscing elit. Cras tincidunt tortor sit amet pretium semper. Pellentesque ac laoreet nulla. Fusce quis sapien ut magna ornare lacinia condimentum vel dui. Pellentesque volutpat pulvinar facilisis. Nunc lacus justo, imperdiet a urna at, condimentum gravida erat. \nAliquam ornare mi id dui blandit laoreet. Donec sed \nelit pretium arcu elementum lobortis ac at est. Curabitur nec \nsapien quam. Duis sit amet lectus quis odio finibus viverra. Duis dapibus dui a tempus mollis. Vestibulum porta sem id tristique maximus. Fusce molestie purus ligula, eu auctor mi egestas quis.") t.grid(column = 0, row = 0, sticky = 'nwes') xs.grid(column = 0, row = 1, sticky = 'we') ys.grid(column = 1, row = 0, sticky = 'ns') root.grid_columnconfigure(0, weight = 1) root.grid_rowconfigure(0, weight = 1) root.mainloop() ================================================ FILE: sketch1.py ================================================ from tkinter import * from tkinter import ttk lastx, lasty = 0, 0 def xy(event): global lastx, lasty lastx, lasty = event.x, event.y def addLine(event): global lastx, lasty canvas.create_line(lastx, lasty, event.x, event.y) lastx, lasty = event.x, event.y root = Tk() root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) canvas = Canvas(root) canvas.grid(column=0, row=0, sticky=(N, W, E, S)) canvas.bind("", xy) canvas.bind("", addLine) root.mainloop() ================================================ FILE: sketch2.py ================================================ from tkinter import * from tkinter import ttk lastx, lasty = 0, 0 color = "black" def xy(event): global lastx, lasty lastx, lasty = event.x, event.y def setColor(newcolor): global color color = newcolor def addLine(event): global lastx, lasty canvas.create_line(lastx, lasty, event.x, event.y, fill=color) lastx, lasty = event.x, event.y root = Tk() root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) canvas = Canvas(root) canvas.grid(column=0, row=0, sticky=(N, W, E, S)) canvas.bind("", xy) canvas.bind("", addLine) id = canvas.create_rectangle(10, 10, 30, 30, fill="red") canvas.tag_bind(id, "", lambda x: setColor("red")) id = canvas.create_rectangle(10, 35, 30, 55, fill="blue") canvas.tag_bind(id, "", lambda x: setColor("blue")) id = canvas.create_rectangle(10, 60, 30, 80, fill="black") canvas.tag_bind(id, "", lambda x: setColor("black")) root.mainloop() ================================================ FILE: sketch3.py ================================================ from tkinter import * from tkinter import ttk lastx, lasty = 0, 0 color = "black" def xy(event): global lastx, lasty lastx, lasty = event.x, event.y def setColor(newcolor): global color color = newcolor canvas.dtag('all', 'paletteSelected') canvas.itemconfigure('palette', outline='white') canvas.addtag('paletteSelected', 'withtag', 'palette%s' % color) canvas.itemconfigure('paletteSelected', outline='#999999') def addLine(event): global lastx, lasty canvas.create_line(lastx, lasty, event.x, event.y, fill=color, width=5, tags='currentline') lastx, lasty = event.x, event.y def doneStroke(event): canvas.itemconfigure('currentline', width=1) root = Tk() root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) canvas = Canvas(root) canvas.grid(column=0, row=0, sticky=(N, W, E, S)) canvas.bind("", xy) canvas.bind("", addLine) canvas.bind("", doneStroke) id = canvas.create_rectangle(10, 10, 30, 30, fill="red", tags=('palette', 'palettered')) canvas.tag_bind(id, "", lambda x: setColor("red")) id = canvas.create_rectangle(10, 35, 30, 55, fill="blue", tags=('palette', 'paletteblue')) canvas.tag_bind(id, "", lambda x: setColor("blue")) id = canvas.create_rectangle(10, 60, 30, 80, fill="black", tags=('palette', 'paletteblack', 'paletteSelected')) canvas.tag_bind(id, "", lambda x: setColor("black")) root.mainloop() ================================================ FILE: sketch4.py ================================================ from tkinter import * from tkinter import ttk root = Tk() h = ttk.Scrollbar(root, orient=HORIZONTAL) v = ttk.Scrollbar(root, orient=VERTICAL) canvas = Canvas(root, scrollregion=(0, 0, 1000, 1000), yscrollcommand=v.set, xscrollcommand=h.set) h['command'] = canvas.xview v['command'] = canvas.yview canvas.grid(column=0, row=0, sticky=(N,W,E,S)) h.grid(column=0, row=1, sticky=(W,E)) v.grid(column=1, row=0, sticky=(N,S)) root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(0, weight=1) lastx, lasty = 0, 0 def xy(event): global lastx, lasty lastx, lasty = canvas.canvasx(event.x), canvas.canvasy(event.y) def setColor(newcolor): global color color = newcolor canvas.dtag('all', 'paletteSelected') canvas.itemconfigure('palette', outline='white') canvas.addtag('paletteSelected', 'withtag', 'palette%s' % color) canvas.itemconfigure('paletteSelected', outline='#999999') def addLine(event): global lastx, lasty x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) canvas.create_line(lastx, lasty, x, y, fill=color, width=5, tags='currentline') lastx, lasty = x, y def doneStroke(event): canvas.itemconfigure('currentline', width=1) canvas.bind("", xy) canvas.bind("", addLine) canvas.bind("", doneStroke) id = canvas.create_rectangle(10, 10, 30, 30, fill="red", tags=('palette', 'palettered')) canvas.tag_bind(id, "", lambda x: setColor("red")) id = canvas.create_rectangle(10, 35, 30, 55, fill="blue", tags=('palette', 'paletteblue')) canvas.tag_bind(id, "", lambda x: setColor("blue")) id = canvas.create_rectangle(10, 60, 30, 80, fill="black", tags=('palette', 'paletteblack', 'paletteSelected')) canvas.tag_bind(id, "", lambda x: setColor("black")) setColor('black') canvas.itemconfigure('palette', width=5) root.mainloop() ================================================ FILE: sketcho.py ================================================ from tkinter import * from tkinter import ttk class Sketchpad(Canvas): def __init__(self, parent, **kwargs): super().__init__(parent, **kwargs) self.bind("", self.save_posn) self.bind("", self.add_line) def save_posn(self, event): self.lastx, self.lasty = event.x, event.y def add_line(self, event): self.create_line(self.lastx, self.lasty, event.x, event.y) self.save_posn(event) root = Tk() root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) sketch = Sketchpad(root) sketch.grid(column=0, row=0, sticky=(N, W, E, S)) root.mainloop() ================================================ FILE: stackorder.py ================================================ from tkinter import * from tkinter import ttk root = Tk() little = ttk.Label(root, text="Little") bigger = ttk.Label(root, text='Much bigger label') little.grid(column=0,row=0) bigger.grid(column=0,row=0) root.after(2000, lambda: little.lift()) root.mainloop() ================================================ FILE: validate.py ================================================ from tkinter import * from tkinter import ttk root=Tk() import re errmsg = StringVar() formatmsg = "Zip should be ##### or #####-####" def check_zip(newval, op): errmsg.set('') valid = re.match('^[0-9]{5}(\-[0-9]{4})?$', newval) is not None btn.state(['!disabled'] if valid else ['disabled']) if op=='key': ok_so_far = re.match('^[0-9\-]*$', newval) is not None and len(newval) <= 10 if not ok_so_far: errmsg.set(formatmsg) return ok_so_far elif op=='focusout': if not valid: errmsg.set(formatmsg) return valid check_zip_wrapper = (root.register(check_zip), '%P', '%V') zip = StringVar() f = ttk.Frame(root) f.grid(column=0, row=0) ttk.Label(f, text='Name:').grid(column=0, row=0, padx=5, pady=5) ttk.Entry(f).grid(column=1, row=0, padx=5, pady=5) ttk.Label(f, text='Zip:').grid(column=0, row=1, padx=5, pady=5) e = ttk.Entry(f, textvariable=zip, validate='all', validatecommand=check_zip_wrapper) e.grid(column=1, row=1, padx=5, pady=5) btn = ttk.Button(f, text="Process") btn.grid(column=2, row=1, padx=5, pady=5) btn.state(['disabled']) msg = ttk.Label(f, font='TkSmallCaptionFont', foreground='red', textvariable=errmsg) msg.grid(column=1, row=2, padx=5, pady=5, sticky='w') root.mainloop()