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: