Tkinter
Rozvržení widgetů
V této kapitole stručně popíšeme tři systémy rozvržení (layout managers) nebo správce geometrie, jak jsou rovněž někdy označováni:- pack
- grid
- place
- umisťují widgety na obrazovce
- registrují widgety v nativním okenním (windowing) systému
- spravují zobrazení widgetů na obrazovce
Umístění widgetů na obrazovce zahrnuje určení velikosti a pozice jednotlivých komponent. Byť jsou widgety nositeli prvotní informace o velikosti a přiřazení, poslední slovo o jejich umístění a velikosti mají správci geometrie.
Pack
Systém "pack" má jednoduchý, byť obtížně vysvětlitelný algoritmus. Organizuje widgety do bloků před jejich umístěním do nadřazeného okna; někdy je nutné vložit pomocný rámeček (frame). Místo přesného absolutního určení pozice widgetu lze pozici určit relativně vzhledem k jinému widgetu. O detaily se postará metoda pack().Byť snadno použitelný, ve srovnání se správci "grid" a "place" jsou možnosti tohoto správce poněkud omezené. Pro jednoduché aplikace (umístění řady widgetů vedle sebe nebo nad sebou) je to určitě správce nejvhodnější.
Příklad:
from tkinter import * root = Tk() Label(root, text="Red Sun", bg="red", fg="white").pack() Label(root, text="Green Grass", bg="green", fg="black").pack() Label(root, text="Blue Sky", bg="blue", fg="white").pack() mainloop()
Parametr fill
V naší ukázce jsme "napakovali" tři widgety do rodičovského widgetu "root". Použili jsme pack() bez jakýchkoliv parametrů. Takže o uspořádání popisků musel "pack" rozhodnout sám. Jak vidno, rozhodl se umístit widgety popisků centricky jeden nad druhý. Navíc vidíme, že velikosti popiskových widgetů jsou dány délkou vložených textů. Chcete-li, aby byly widgety popisků stejně široké jako rodičovský widget, můsíte použít parametr fill=X:from tkinter import * root = Tk() w = Label(root, text="Red Sun", bg="red", fg="white") w.pack(fill=X) w = Label(root, text="Green Grass", bg="green", fg="black") w.pack(fill=X) w = Label(root, text="Blue Sky", bg="blue", fg="white") w.pack(fill=X) mainloop()
Výstelka
Správce pack() zná čtyři možnosti výstelky neboli odsazení: vnitřní, vnější, ve směru x a směru y:padx - externí výstelka horizontálně
from tkinter import * root = Tk() w = Label(root, text="Red Sun", bg="red", fg="white") w.pack(fill=X,padx=10) w = Label(root, text="Green Grass", bg="green", fg="black") w.pack(fill=X,padx=10) w = Label(root, text="Blue Sky", bg="blue", fg="white") w.pack(fill=X,padx=10) mainloop()
pady - externí výstelka vertikálně
from tkinter import * root = Tk() w = Label(root, text="Red Sun", bg="red", fg="white") w.pack(fill=X,pady=10) w = Label(root, text="Green Grass", bg="green", fg="black") w.pack(fill=X,pady=10) w = Label(root, text="Blue Sky", bg="blue", fg="white") w.pack(fill=X,pady=10) mainloop()
ipadx - vnitřní výstelka horizontálně.
V následujícím příkladě změníme pouze popisek s textem "Green Grass" tak, aby byl lépe čitelný. Odstraníme také parametr fill.
from Tkinter import * root = Tk() w = Label(root, text="Red Sun", bg="red", fg="white") w.pack() w = Label(root, text="Green Grass", bg="green", fg="black") w.pack(ipadx=10) w = Label(root, text="Blue Sky", bg="blue", fg="white") w.pack() mainloop()
ipady - Vnitřní výstelka svisle
Poslední popisek předchozího příkladu změníme s ipady=10.
from tkinter import * root = Tk() w = Label(root, text="Red Sun", bg="red", fg="white") w.pack() w = Label(root, text="Green Grass", bg="green", fg="black") w.pack(ipadx=10) w = Label(root, text="Blue Sky", bg="blue", fg="white") w.pack(ipady=10) mainloop()
Implicitní hodnota ve všech případech je 0.
Umístění widgetů vedle sebe
Chceme nyní umístit tři popisky vedle sebe a lehce zkrátit text:
Příslušný kód vypadá takto:
from tkinter import * root = Tk() w = Label(root, text="red", bg="red", fg="white") w.pack(padx=5, pady=10, side=LEFT) w = Label(root, text="green", bg="green", fg="black") w.pack(padx=5, pady=20, side=LEFT) w = Label(root, text="blue", bg="blue", fg="white") w.pack(padx=5, pady=20, side=LEFT) mainloop()
Když v předchozím příkladě změníme LEFT na RIGHT, dostaneme barvy v obráceném pořadí:
Place
Systém "place" umožňuje explicitně zadat pozici a velikost okna a to buď absolutně nebo relativně k jinému oknu. Lze jej použít pro všechny standardní widgety.Použijeme jej v následujícím příkladě, kde si hrajeme s barvami, když každému popisku přisoudíme jinou barvu, kterou určíme náhodně s použitím metody randrange() modulu random. Počítáme jas (brightness) každé barvy. Je-li jas menší než 120, nastavíme barvu popředí (fg) na White, jinak na Black a to proto aby byl text snáze čitelný.
import tkinter as tk import random root = tk.Tk() # (width x height + x_offset + y_offset) root.geometry("170x200+30+30") languages = ['Python','Perl','C++','Java','Tcl/Tk'] labels = range(5) for i in range(5): ct = [random.randrange(256) for x in range(3)] brightness = int(round(0.299*ct[0] + 0.587*ct[1] + 0.114*ct[2])) ct_hex = "%02x%02x%02x" % tuple(ct) bg_colour = '#' + "".join(ct_hex) l = tk.Label(root, text=languages[i], fg='White' if brightness < 120 else 'Black', bg=bg_colour) l.place(x = 20, y = 30 + i*30, width=120, height=25) root.mainloop()
Grid
Správce "grid" je v mnoha případech nejlepší volbou. Je flexibilnější než "pack" a méně pracný než "place".Systém grid umisťuje widgety do buněk dvojrozměrného rastru, který se skládá z řádků a sloupců. Pozice widgetu je daná číslem řádku a sloupce. Sousední buňky lze vhodně spojovat.
Zadání pozice widgetu je mnohdy postačující, neboť správce grid umí sám určit jeho nejvhodnější rozměr.
Přiklad s grid
from tkinter import * colours = ['red','green','orange','white','yellow','blue'] r = 0 for c in colours: Label(text=c, relief=RIDGE, width=15) .grid(row=r,column=0) Entry(bg=c, relief=SUNKEN,width=10).grid(row=r,column=1) r = r + 1 mainloop()