Tkinter
Entry Widget
Widgety Entry jsou základní objekty Tkinteru pro vkládání vstupních údajů od uživatele, například řetězců. Tento widget umožní zadat jeden řádek textu. Zadá-li uživatel řetězec, který je delší než vymezené místo ve widgetu, je viditelná pouze jeho část. Ke zviditelnění zakrytých částí lze použít klávesnice se šipkami. Potřebujeme-li zadat víceřádkový text, použijeme widget Text.
Deklarace objektu Entry vypadá takto:
w = Entry(master, option, ... )
Parametr "master" představuje rodičovské okno, ve kterém má být widget "entry" umístěn. Stejně jako u ostatních widgetů je možné dále ovlivnit vzhled widgetu použitím parametrů.
Následující příklad vytváří aplikaci se dvěma vstupními poli. Jedno pro zadání křestního jména, druhé pro zadání příjmení.
from tkinter import * master = Tk() Label(master, text="First Name").grid(row=0) Label(master, text="Last Name").grid(row=1) e1 = Entry(master) e2 = Entry(master) e1.grid(row=0, column=1) e2.grid(row=1, column=1) mainloop( )Okno, vytvořené předcházejícím skriptem, vypadá takto:
Nuže, vytvořili jsme vstupní pole, do nichž může uživatel vkládat nějaká data. Jak se ale program k těmto datům dostane, jak přečte obsah vstupních polí?
Jednoduše - použijeme metodu get(). Rozšíříme náš malý skript o dvě tlačítka "Quit" a "Show". Propojíme funkci show_entry_fields(), která používá metodu get() pro objekty Entry, s tlačítkem Show. Při každém poklepu tohoto tlačítka se obsah vstupního pole vytiskne na terminálu, ze kterého byl skript spuštěn.
from tkinter import * def show_entry_fields(): print("First Name: %s\nLast Name: %s" % (e1.get(), e2.get())) master = Tk() Label(master, text="First Name").grid(row=0) Label(master, text="Last Name").grid(row=1) e1 = Entry(master) e2 = Entry(master) e1.grid(row=0, column=1) e2.grid(row=1, column=1) Button(master, text='Quit', command=master.quit) .grid(row=3, column=0, sticky=W, pady=4) Button(master, text='Show', command=show_entry_fields) .grid(row=3, column=1, sticky=W, pady=4) mainloop( )
Kompletní výsledek vypadá takto:
Předpokládejme nyní, že chceme spouštět aplikaci s přednastavenými hodnotami (např. Jill Miller) ve vstupních polích. Nová verze našeho programu dostane následující dva řádky, které mohou být přidány za definicemi vstupních polí (e2 = Entry(master)):
e1.insert(10,"Jill") e2.insert(10,"Miller")
Což takhle smazávat obsah vstupního pole po každém jeho zobrazení v terminálu? Žádný problém. Použijeme metodu delete(). Tato metoda má formát delete(first, last=None). Je-li zadáno pouze jedno číslo, je považováno za index a smaže se odpovídající alfanumerický znak. Jsou-li zadána dvě čísla, tvoří hranice rozsahu (range) a vymaže se odpovídající rozsah znaků. Pro vymazávání veškerého textu zadáváme delete(0, END).
from tkinter import * def show_entry_fields(): print("First Name: %s\nLast Name: %s" % (e1.get(), e2.get())) e1.delete(0,END) e2.delete(0,END) master = Tk() Label(master, text="First Name").grid(row=0) Label(master, text="Last Name").grid(row=1) e1 = Entry(master) e2 = Entry(master) e1.insert(10,"Miller") e2.insert(10,"Jill") e1.grid(row=0, column=1) e2.grid(row=1, column=1) Button(master, text='Quit', command=master.quit) .grid(row=3, column=0, sticky=W, pady=4) Button(master, text='Show', command=show_entry_fields) .grid(row=3, column=1, sticky=W, pady=4) mainloop( )
Další příklad ukazuje, jak můžeme elegantně vytvářed řadu vstupních polí více pythonovským způsobem. Pro jejich popis použijeme seznam Pythonu, který do aplikace vložíme jako popisky.
from tkinter import * fields = 'Last Name', 'First Name', 'Job', 'Country' def fetch(entries): for entry in entries: field = entry[0] text = entry[1].get() print('%s: "%s"' % (field, text)) def makeform(root, fields): entries = [] for field in fields: row = Frame(root) lab = Label(row, width=15, text=field, anchor='w') ent = Entry(row) row.pack(side=TOP, fill=X, padx=5, pady=5) lab.pack(side=LEFT) ent.pack(side=RIGHT, expand=YES, fill=X) entries.append((field, ent)) return entries if __name__ == '__main__': root = Tk() ents = makeform(root, fields) root.bind('<Return>', (lambda event, e=ents: fetch(e))) b1 = Button(root, text='Show', command=(lambda e=ents: fetch(e))) b1.pack(side=LEFT, padx=5, pady=5) b2 = Button(root, text='Quit', command=root.quit) b2.pack(side=LEFT, padx=5, pady=5) root.mainloop()
Spuštěný skript vypadá takto:
Kalkulátor
Úplný kalkulátor nevytvoříme ale sestavíme GUI, ve kterém lze matematický výpočet provést a výsledek vytisknout.from tkinter import * from math import * def evaluate(event): res.configure(text = "Ergebnis: " + str(eval(entry.get()))) w = Tk() Label(w, text="Your Expression:").pack() entry = Entry(w) entry.bind("<Return>", evaluate) entry.pack() res = Label(w) res.pack() w.mainloop()
Naše aplikace vypadá takto:
Výpočet úroku
Následující vzorec lze použít k výpočtu zůstatku Bk po provedených k platbách, počínaje počáteční hodnotou půjčky Bo a úrokovou mírou r:kde
rate = roční úroková míra v procentech, např. 3 %
i = rate / 100, roční úroková míra v decimální formě
r = úroková míra období = i / 12
B0 = hodnota půjčky (loan principle)
Bk = výše dluhu po k platbách
k = počet měsíčních splátek
p = měsíční splátka (monthly payment)
Chceme-li určit nezbytnou měsíční splátku, má-li být půjčka splacena v zadaných n splátkách, nastavíme Bn = 0 a dostaneme vzorec:
kde
n = počet měsíčních splátek
from tkinter import * fields = ('Annual Rate', 'Number of Payments', 'Loan Principle', 'Monthly Payment', 'Remaining Loan') def monthly_payment(entries): # period rate: r = (float(entries['Annual Rate'].get()) / 100) / 12 print("r", r) # principal loan: loan = float(entries['Loan Principle'].get()) n = float(entries['Number of Payments'].get()) remaining_loan = float(entries['Remaining Loan'] .get()) q = (1 + r)** n monthly = r*( (q*loan - remaining_loan) / ( q - 1 )) monthly = ("%8.2f" % monthly).strip() entries['Monthly Payment'].delete(0,END) entries['Monthly Payment'].insert(0, monthly ) print("Monthly Payment: %f" % monthly) def final_balance(entries): # period rate: r = (float(entries['Annual Rate'].get()) / 100) / 12 print("r", r) # principal loan: loan = float(entries['Loan Principle'].get()) n = float(entries['Number of Payments'].get()) q = (1 + r)** n monthly = float(entries['Monthly Payment'].get()) q = (1 + r)** n remaining = q * loan - ( (q - 1) / r) * monthly remaining = ("%8.2f" % remaining).strip() entries['Remaining Loan'].delete(0,END) entries['Remaining Loan'].insert(0, remaining ) print("Remaining Loan: %f" % remaining) def makeform(root, fields): entries = {} for field in fields: row = Frame(root) lab = Label(row, width=22, text=field+": ", anchor='w') ent = Entry(row) ent.insert(0,"0") row.pack(side=TOP, fill=X, padx=5, pady=5) lab.pack(side=LEFT) ent.pack(side=RIGHT, expand=YES, fill=X) entries[field] = ent return entries if __name__ == '__main__': root = Tk() ents = makeform(root, fields) root.bind('<Return>', (lambda event, e=ents: fetch(e))) b1 = Button(root, text='Final Balance', command=(lambda e=ents: final_balance(e))) b1.pack(side=LEFT, padx=5, pady=5) b2 = Button(root, text='Monthly Payment', command=(lambda e=ents: monthly_payment(e))) b2.pack(side=LEFT, padx=5, pady=5) b3 = Button(root, text='Quit', command=root.quit) b3.pack(side=LEFT, padx=5, pady=5) root.mainloop()
Náš úrokový kalkulátor vypadá následovně, pokud je spustíme v Pythonu3: