Tkinter/Otázky a odpovědi
Tato stránka je součástí projektu: | |
Příslušnost: Juandev |
Doplňový studijní nástroj pro seznámení se s Tkinter slouží jako doplnění Vašeho osobního studia. Používá se tak, že si zde zapisujete otázky a sami si k nim na internetu (chatGPT, YouTube, diskusní skupiny) hledáte odpovědi, které pak také zapíšete. V rámci procvičování porozumění danému tématu můžete také zodpovědět otázky, bez odpovědí.
Nástroj má tři sekce. V první jsou všemožné otázky a odpovědi týkající se knihovny Tkinter. Do druhé se dávají chybové hlášení a jejích řešení. Poslední sekce je věnována souvisejícím problémům.
Otázky a odpovědi
[editovat]Do této tabulky patří všemožné otázky týkající se knihovny Tkinter. Kód se označuje jako kód nebo blok kódu v nástrojích vizuálního editoru. Můžete připojit i soubory nákresů.
Č. | Otázka | Odpověď | Poznámky |
---|---|---|---|
OO.1 | Proč je metoda Grid() navázána na Widget Entry ?
|
Grid() není metoda, ale geometrický manager. Každý widget (jako např. Entry() ) má k dispozici různé geometrické managery dle logiky věci. Znanemá to, že existují widgety, které nemají k dispozici všechny geometrické managery.
|
|
OO.2 | Jaké jsou typy managerů geometrie? |
|
|
OO.3 | Je možné absolutní rozležení prvků? | ||
OO.4 | Co je to rowspan? | ||
OO.5 | Jaký je rozdíl mezi rowspan a columnspan? | ||
OO.6 | Je place() metoda?
|
Ano, viz: tutorialspoint.com/python/tk_place.htm. | |
OO.7 | Jak se pracuje z columnconfigure()? | ||
OO.8 | Co je to frame? | ||
OO.9 | Jak rozumět zápisu: {'background': ('background', 'frameColor', 'FrameColor', '', ''), 'foreground': ('foreground', 'textColor', 'TextColor', '', ''), 'font': ('font', 'font', 'Font', '', ''), 'borderwidth': ('borderwidth', 'borderWidth', 'BorderWidth', '', ''), 'relief': ('relief', 'relief', 'Relief', '', ''), 'anchor': ('anchor', 'anchor', 'Anchor', '', ''), 'justify': ('justify', 'justify', 'Justify', '', ''), 'wraplength': ('wraplength', 'wrapLength', 'WrapLength', '', ''), 'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', '', ''), 'text': ('text', 'text', 'Text', '', ''), 'textvariable': ('textvariable', 'textVariable', 'Variable', '', ''), 'underline': ('underline', 'underline', 'Underline', -1, -1), 'width': ('width', 'width', 'Width', '', ''), 'image': ('image', 'image', 'Image', '', ''), 'compound': ('compound', 'compound', 'Compound', '', ''), 'padding': ('padding', 'padding', 'Pad', '', ''), 'state': ('state', 'state', 'State', <index object: 'normal'>, <index object: 'normal'>), 'cursor': ('cursor', 'cursor', 'Cursor', '', ''), 'style': ('style', 'style', 'Style', '', ''), 'class': ('class', '', '', '', '')} ?
|
Jedná se o slovník, který obsahuje v kulatých závorkách pro jednotlivé možnosti (options) n-tice (tuple). Jednotlivé pozice v ntici, od první:
|
|
OO.10 | Jak zjistím jaké jsou volitelné hodnoty pro možnosti metody .configure() ?
|
Například v Tk docs hledat "configuration options" v jednotlivých widgetech. | |
OO.11 | Mohu metodou get() získat text z popisu widgetu Label?
|
Možná, v nápovědě příkazu gets jazyka Tcl je napsáno, že sbírá data pouze z kanálů (tj. stdin, stdout a stderr).
|
Proč se zde odkazujeme na nápovědu jazyka Tcl je vysvětleno v řádce 12. |
OO.12 | Existuje nějaká one page documentace pro Tkinter? | Ne. Je to jako Vicuna, někdo vyvine skvělou aplikaci, ale pak ji nejsme schopni plně užíváte, protože nevíme co jak funguje. | Dobře mohou posloužit tyto odkazy
Dále možnosti konfigurace jednotlivých widgetů se hledají přes "configuration options" v Tk docs pro každý widtet zvášť. |
OO.13 | Jak zjistím jakou mám verzi Tcl? | import tkinter as tk
tcl_version = tk.TclVersion
print("Tcl Version:", tcl_version)
|
|
OO.14 | Kdy vyšla verze Tcl 8.6? | V prosinci 2012. | |
OO.15 | Je get() metoda z tkinter? | Zdá se že ano. | |
OO.16 | Co je to <index object: 'normal'> v otázce číslo 9?
|
||
OO.17 | Jak vypíšu hodnoty pro možnosti? | ||
OO.18 | Je kanálem stdin můj vlastní skript? | ||
OO.19 | Co dělá metoda .StringVar() ?
|
Metoda StringVar() může držet hodnoty typu řetězec určitého widgetu a podle potřeby je updatovat. Na widget je napojena přes atrribut textvariable. Byť drží hodnoty typu řetězec může přebírat i číselné hodnoty, se kterými pak pracuje jako s řetězci.
|
|
OO.20 | Jak se zadávají indexy při configurování widgetu s možností underline? | Může se zadat pouze jeden index, protože primárně neslouží k podtrhávání textu, ale k něčemu jinému (např. 0 je první index, 1 druhý, atd. Vždy jde zadat ale jen jeden index a zadává se prostě číslem.)
|
|
OO.21 | Jaké metody jsou podobné tk.StringVar() ?
|
IntVar() pro celá čísla, DoubleVar() pro čísla s desetinou čárkou, BooleanVar() pro hodnoty True/False a využívá se hlavně v zaškrtávácích listech.
|
Nicméně i IntVar() umí přenášet řetězce, tzn. pokud se do pole kam je přiřazn IntVar() vloží řetězec, tak ho předává jako řetězec.
|
OO.22 | Jaký je atribut widgetu pro IntVar() ?
|
textvariable
|
|
OO.23 | Jak se řekne česky checkbutton? | zaškrtávací pole | |
OO.24 | Jak se řekne česky radiobutton? | přepínač | |
OO.25 | Kolik znaků se vejde do widgetu Entry? | Limit není, ale může se stanovit, třeba proto, aby se nepřetížil systém, když by někdo do widgetu vkládal velké množství textu. Některé aplikace využívající REPL, mohou ale mít vlastní limitaci. | |
OO.26 | Má ttk.Checkbutton() atribut value ?
|
Nemá, ale stejným způsobem se používá atribut variable .
|
|
OO.27 | Jak důležité je pořadí atributů ve funkci? | ||
OO.28 | Je možné mít v atributu command 2 hodnoty? | Ne, ale dá se to docílit tím, že z atributu command volám funkci, která v sobě zahrnuje dvě jiné funkce, které něco dělají....
def funkce_1():
...
def funkce_2():
...
def wrapper_function():
funkce_1()
funkce_2()
...
tlacitko = ttk.Button(root, text="Tlačítko", command=wrapper_function).pack()
...
|
Takže hodnotou atributu command je wrapper_functio n, která je definávána jako funkce 1 a 2.
|
OO.29 | Může mít onvalue a offvalue dvě hodnoty? | Ne | |
OO.30 | Metoda get() na čudlících dává výstupy v podobě 0/1?
|
||
OO.31 | Jak vypadá hodnota události Motion ?
|
<Motion event state=Mod2 x=528 y=255>
|
1) state=Mod2 znamená, že byl na zařízení Linux stisknutý num lock (ale na každém operačním systému to znamená něco jiného). 2) x=528 znamená, že kurzor je 528 pixelů doprava od horizontálního okraje daného widgetu, a 3) y=255 znamená, že je kurzor 255 px dolů od okraje daného widgetu. Díky 2) a 3) tak lze zjistit pozici kurzoru na widgetu na kterém pozici sleduje událost Motion . Pokud hodnotě Motion přidělíme nějaký placeholder, můžeme pak získávat jednotlivé vlastnosti. Například:def vyplyvne_hodnotu(motion):
print(f"Aktivní klávesy: {motion.state}, kurzor se ti propadl až na {motion.y} pixlů.")
|
OO.32 | Co značí výpis 140227336851328<lambda> objevující se v konzoli při spuštění programu?
|
Je to adresa konkrétní lambda funkce v paměti Pythonu (číslo) a označení, že se jedná o lambda funkci (<lambda> ). Python to vypisuje automaticky a má to jen tento význam.
|
|
OO.33 | Jaký datový typ označují ostré závorky (<> )?
|
Žádný, jedná se o určité formátování. | |
OO.34 | Co je to událost? Jak se do proměnné předávají informace o události? | Některé události do proměné předávají datový objekt (např. řetězec), který obsahuje informace, které daný typ události generuje, jindy funkce bind() pouze zapíná následnou funkci (tedy pokud mám například zadán typ události <KeyPress> a následuje funkce print("stisknuto tlačítko") pak v případě kdy s myší umístěnou nad daným widgetem kliknu na klávesnici na jakoukoliv klávesu, tak Tkinter provede danou funkci, tedy vypíše do konzole stisknuto tlačítko. Obecně by se to dalo zapsat jako widget.bind("<označení eventu>", funkce k provedení v případě True na označení eventu) . Anglicky se tomu říká event binding, odtud název metody widget.bind() . Vedle této metody umožňuje Tkinter některé události předávat pomocí atributu command.
|
|
OO.35 | Jak se jmenuje označení eventu (například <Shift> ?
|
Typ události (angl. event type). | |
OO.36 | Lze zpracovat označení eventu vícekrát? | Ano, ale u druhého zpracování, které jde na nový řádek se musí dát atribut add=+ .
|
|
OO.37 | Proč se mi bindne událost s funkcí při zadání <Shift_L> , ale ne při zadání <Shift> ?
|
Protože to tkinter neumí. <Shift> je modifikátor a čeká se, že bude stisknut s něčím, proto musím volit detailní eventy Shift_L (pro stisk levého shiftu) a Shift_R (pro stisk pravého shiftu).
|
|
OO.38 | Proč detailní události fungují, jen při označení daného widgetu (např. při zadání detailních událostí na widgetu text)? | Protože v tkinteru jde připojovat události jen na aktivní widgety. Proto napřed musím kliknout do pole text a pak mohu něco stisknout, aby mi zafungoval typ události. Respetive, pokud bych připojoval události typu pozice kurzoru, pak mi stačí danný widget pouze přejet. Pozice kurzoru (<Motion> ) je totiž spojena s myší, kdežto většina ostatních je spojena s klávesnicí a tak jediný způsob aktivace je kliknutím a umístění kurzoru do daného widgetu.
|
|
OO.39 | Proč mi nic nedělá událost typu <MouseWheel> ?
|
Protože mám Linux na kterém je X11 systém a ten událost <MouseWheel> nepodporuje. Místo toho zavádí <Button-4> událost pro scrollování nahoru a <Button-5> pro scrollování dolů.
|
|
OO.40 | Co je to windowing system? | ||
OO.41 | Proč nefunguje <Shift-Button-4> ?
|
Protože událost <Shift-Button-4> registruje na systémech X11 (Linux) horizontální pohyb kurzoru. Závisí pak jaký hardware ten horizontální pohyb zajišťuje, tzn. nemusí to být držení klávesy Shift a zároveň otáčení kolečka myši, jak by se mohlo zdát.
|
|
OO.42 | K čemu je atribut textvariable ?
|
Textvariable je atribut, který umožňuje přidat k widgetu proměnou a propojit ji s třídami typu StringVar . To pak umožňuje provádět změny daného hodnoty na obou stranách.
|
|
OO.43 | Jak se obecně říká třídám jako StringVar , IntVar , DoubleVar apod.?
|
Proměnné knihovny Tkinter (Tkinter variables) či speciální třídy proměných (special variable classes). | |
OO.44 | Proč má událost typu <<ComboboxSelected>> kolem sebe dvě ostré závorky na místo jedné?
|
Protože se jedná o virtuální událost. Byť označení položky v Comboboxu může být provedeno myší, může být zároveň provedeno i touchpedem či programaticky. Není to tedy událost, která by byla svázána s nějakým druhem hardwaru, ale je to tzv. virtuální událost. | |
OO.45 | Proč se dávají typy událostí do ostrých závorek? | Je to zejména pro jejich zvýraznění. Když je to v ostrých závorkách, tak je to v Tkinteru nějaká událost. Jedny ostré závorky (<> ) označují záznam události, které provedl uživatel fyzicky, dvě ostré závorky (<<>> ) pak zaznamenávají abstraktnější akce, proto se jim říká virtuální události.
|
|
OO.46 | Co se označuje kapitálkama (jako například tk.END jako hodnota atributu index )?
|
Je to konstanta, která představuje koncovou pozici v indexu, nebo widgetu. Tzn. pokud něco vložím do funkce a zároveň tam mám atribut tk.END, tak mi to tu hodnotu vloží na konec výpisu.
...
tabulka.insert(parent= "", index = tk.END, values = ("x", "y", "z"))
...
|
|
OO.47 | Co je to například ('I046',) při volání table.selection s použitím události <<TreeviewSelect>> ?
|
Číslo položky, respetive řádku v tabulce. | |
OO.48 | Co značí atribut a hodnota parent = "" v metodě insert() ?
|
Prázdná řetězcová hodnota atributu parent označuje, že hodnoty vládané touto funkcí jsou přivázány ke kořenovému uzlu. Uzly (angl. nodes) v datové vědě obvykle označují bloky textu, nebo dat, na které jsou navázány další uzly. V případě tabulky v treeview je takovým uzlem řádek a kořenovým uzlem je pak první řádek, který ale Tkinter nezobrazuje. Vytváří ho proto, aby z něj udělal "parent node" pro následující "child nodes".
|
|
OO.49 | Existují v knihovně další konstanty jako END ?
|
Ano, například NORMAL (představuje normální stav tlačítka), ACTIVE (představuje stav tlačítka, kdy je s ním prováděna nějaká interakce), NE (směr ukotvení obsahu ve Widgetu), apod. | |
OO.50 | Co je to treeview? | Je to grafický widget, který připomíná taxonomický strom obsahující text. | |
OO.51 | Co dělá funkce choice() ?
|
Je součástí knihovny random a náhodně vybírá prvky z nějakého souboru.
|
|
OO.52 | Co dělá funkce selection() ?
|
Používá se ve widgetu treeview a vybírá aktuálně vybrané (uživatelem vybrané) položky. | |
OO.53 | Co dělá funkce item() ?
|
Na widgetu treeview získává informace o určité položce. | |
OO.54 | Proč je za kulatou závorkou, ještě hranatá: print(tabulka.item(i)["values"]) ?
|
Protože v kulaté závorce jsou parametry funkce a vždy se dávají do kulaté závorky. A dále proto, že data v položkách widgetu Treeview jsou uloženy ve slovnících a klíče slovníků se volají vložením do hranatých závorek. | |
OO.55 | Co dělá typo funkce <Delete> ?
|
||
OO.56 | Proč má from_ podtržítko?
|
Protože from je klíčové slovo z jádra Pythona, tak aby se to odlišilo.
|
|
OO.57 | Jaké hodnoty má atribut orient ?
|
horizontal , vertical
|
|
OO.58 | Jak definovat směr odkud se hýbe Progressbar() ?
|
||
OO.59 | Je scrolledtext submodul?
|
Ne, jedná se o modul. | |
OO.60 | Proč je scrolledtext třeba importovat?
|
Protože při importu tkinter neimportujeme celou knihovnu, ale hlavní modul tkinter . Takže se neimportují knihovny, ale pouze moduly. Další moduly je pak potřeba importovat separátně. tkinter knihovna je tedy něco jiného než tkinter modul. Dalšími moduly jsou například scrolledtext , ttk , collorchooser , filedialog a další.
|
|
OO.61 | Proč se scrolledtext nanaiportuje z knihovnou tkinter ?
|
Protože zápis import tkinter as ttk , není importem celé knihovny, ale pouze hlavního modulu tkinter v knihovně tkinter . Jasný zápis by tedy mohl být from tkinter import tkinter as tk , ale to se nepoužívá a místo toho se používá ten zkrácený zápis. Ostatní moduly se neimportují a je tedy potřeba importovat všechny separátně. Proto potřebujeme importovat scrolledtext modul: from tkinter import scrolledtext. Toznamená z knihovny tkinter importuj modul scrolledtext .
|
|
OO.62 | Proč se mi nezobrazí progressbar při zadání progressbar_ukol = ttk.Progressbar(
master = okno,
orient = "vertical")
|
Pravděpodobně proto, že widget nemá manager geometrie jako pack() .
|
|
OO.63 | Jaký je rozdíl v použití atributů command a variable na widgetu?
|
Atribut command spouští určitou funkci, až v momentě, kdy je jeho Widget aktivován, například poklepáním myší. Mezi widgety, které mají atribut command patří například Button , Checkbutton , Radiobutton a další.
Variable propojuje atribut s hodnotou Tkinter jako |
|
OO.64 | Která část widgetu progressbar generuje nějaké hodnoty? | ||
OO.65 | Má widget progressbar atribut command? | Nemá | |
OO.66 | Jaké hodnoty obsahuje ttk.Scale ?
|
Jedná se o hodnoty, které jsou ale spojené s pozicí posuvníku, protože se dá udat rozsah hodnot atribut from_ a to .
|
|
OO.67 | Jak rozumět atributům command a variable v tomto kódu: skala_float = tk.DoubleVar
skala = ttk.Scale(
master = okno,
command = lambda hodnota: print(skala_float.get()),
from_ = 0,
to = 25,
length = 500,
orient = "vertical",
variable = skala_float)
skala.pack()
|
Porozumění zobrazuje následující tok zpracování: | |
OO.68 | Co je to metoda pack_propagate() ?
|
Nejedná se o metodu, ale konfigurační možnost geometrického manageru pack, zabránit distribuci hodnot width a height z masteru při zadání hodnoty False . Pokud by byla True , nebo by možnost vůbec nebyla zadána, tak se ohraničení volí právě dle následnických widgetů. Tím pádem se vykreslí rozsahy dle následnicích widgetů.
|
|
OO.69 | Jaké jsou hodnoty atributu side metody pack() ?
|
top (výchozí hodnota), right , bottom a left
|
|
OO.70 | Co je to tk.GROOVE ?
|
Jedná se o konstantu definující styl widgetu. Konstantu je možné aplikovat na widgetech, které umožňují konguraci stran jako Button , Frame , Label , Entry , Text , atd. Dalšími konstantami konfigurace stran jsou například tk.FLAT , tk.RAISED či tk.SUNKEN .
|
|
OO.71 | Co je to konstanta? | Je to proměnná, která by se neměla mněnit. To se programátorovi oznamuje tím, že je zapsána kapitálkami. Viz Python/Juandev#Otázky 24. | |
OO.72 | Jak vložím text do widgetu Entry ?
|
Metodou insert() . Pokud vkládám widget Entry do proměnné vstup , pak třeba následovně: vstup.insert(0, "text") .
|
|
OO.73 | Co znamená hodnota 0 v metodě insert() ?
|
Uvádí index, kam se vloží daný řetězec. Nula je tedy první znak zleva, 1 druhý atd. Pokud by například v poli Entry již byl řetězec FOO, pak následující se následující segment kódu chová následovně:
|
|
OO.74 | Které widgety navíc má ttk narozdíl od modulu tkinter? | Žadné. | |
OO.75 | Ono není nutné přidělovat geometrický manager každému widgetu a stačí ho přidělit jen masterovi? | Geometrický manager je nutné přidělovat všem widgetům. Vyjímkou jsou pouze záložky v rámci widgetu ttk.Notebook (toto nefunguje v tkinter.Notebook ), které se přidělí metodou notebook.add(child) . ttk.Notebook pak automaticky aplikuje managery pack() a grid() na všechny widgety, které volají master Nootebook z metody add() .
V příkladu níže, tvoří jednotlivé záložky widgety ttk.Frame (proměnné tab_1 a tab_2 ). Aby fungovaly jako záložky, nenesou geometrické managery a musí být do ttk.Notebook přidány přes funkci add() ....
notebook = ttk.Notebook(master = okno)
tab_1 = ttk.Frame(notebook)
label_1 = ttk.Label(master = tab_1, text = "Text v záložce 1")
label_1.pack()
tlacitko_1 = ttk.Button(master = tab_1, text "Tlačítko záložky 1")
tlacitko_1.pack()
tab_2 = ttk.Frame(notebook)
label_2 = ttk.Label(tab_2, text = "Text v záložce 2")
label_2.pack()
vstup_2 = ttk.Entry(tab_2)
vstup_2.pack()
notebook.add(tab_1, text = "Tab 1")
notebook.add(tab_2, text = "Tab 2")
notebook.pack()
...
|
Všimněte si, že proměnné tab_1 a tab_2 nemaj explicitně přidělený geometrický manager, zatímco ostatní widgety ano.
To, že je |
OO.76 | Jakých atributů může nabývat metoda add() ?
|
Jako metoda specifická pro ttk.Notebook nabývá hodnot následník a možnosti. V příkladu na řádku 77 je uvedeno notebook.add(tab_1, text = "Tab 1") . tab_1 je v tomto případě označení následníka widgetu notebook (tab_1 = ttk.Frame(notebook) ) a text = "Tab 1" je jedna z možností.
|
|
OO.77 | Kolik generací následovníků může zdědit pack() ?
|
V podstatě žádnou. Jde zde pouze o to, že u widgetu ttk.Notebook se nemusí do kódu pro každou záložku definovanou widgetem ttk.Frame (ani jakýmkoliv jiným widgetem jako např. tkinter.Frame či ttk.Button ) uvádět pack() , protože se to aplikuje z třídy Notebook po přidání widgetu následovníka do masteru přes funkci add() .
|
|
OO.78 | ttk.Frame nemá atribut text ?
|
Nemá, takže pokud využívám ttk.Frame pro tvorbu záložek v ttk.Notebook a chci jim dát nějaký text, musím využít metody add() (která je metodou ttk.Notebook ) a vložit tam text takto.
...
notebook = ttk.Notebook(master = okno)
notebook.pack()
#Záložka 1
tab_1 = ttk.Frame(master = notebook)
#Metoda add() vkládá text do widgetu Frame
notebook.add(tab_1, text = "Toto je záložka 1")
...
|
|
OO.79 | Jaké funkce má metoda add() ?
|
Metoda přidává následovníka do masteru, tedy do widgetu ttk.Notebook . Navíc do widgetu následníka může vkládat text či obrázek.
|
|
OO.80 | Jaký je rozdíl mezi tk.Menu a ttk.Menu ?
|
||
OO.81 | Jaký je rozdíl mezi Menu a Treeview? | Oba widgety jsou v určitém smyslu podobné, nicméně Treeview se využívá hlavně pro zobrazení kořenové strkutury, jakou je třeba struktura adresářů, kdežto Menu jsou spíše obdélné záložky, které se sice také mohou větvit, ale z principu jde spíše o to záložkové zobrazení a poskytnutí odkazů na další funkce a text. | |
OO.82 | Co dělá okno.configure(menu = menu) ?
|
Odkazuje na widget menu na hlavním okně, který se má chovat jako vyskakovací položka. Jinak řečeno menu nalevo je placeholder pro atribut, pravé menu je hodnota, v tomto případě proměnná, kterou je definován Menu widget: menu = tk.Menu(master = okno) . Takže vyskakovací widget se definuje vždy na nadřazeném widgetu. V tomto případě je nadřazeným widgetem okno definované jako tk.Tk() . Pro definici nadřenzených Záložek se ale u subzáložek používá metoda add_cascade() , configure() tam nefunguje.
|
|
OO.83 | Má tk.Menu atribut text? | Nemá. | |
OO.84 | Jaké atributy má tk.Menu ?
|
ŠPATNÁ ODPOVĚD Pouze tearoff (česky odtrhnout), který má dvě Boolean hodnoty True - vytvoří odtržené menu (které vypadá jako separátní okno), a False , které nutí submenu držet s ostatními ve struktuře. Default je True , takže pro tuto funkcionalitu to není třeba definovat.
|
|
OO.85 | Proč se nepřidává k tk.Menu geometrický manager?
|
Protože se jeho pozice definuje automaticky. Vytváří řádek v horní části widgetu hlavního okna do něhož se pak vkládají jednotlivé subzáložky (submenu). | |
OO.86 | Co vytváří tk.Menu ?
|
De facto kořenové Menu (kořenová záložka), které ale není zobrazeno a zobrazit se nedá. K němu se pak přilepují subzáložky. | |
OO.87 | Říká se možnostem metod atributy? | Říká se jim možnosti, ale též atributy. Například tearoff = False v tk.Menu(tearoff=False) , nebo master = okno jsou možnosti. Vlevo je název možnosti (tearoff , master ) vpravo její hodnota (False , okno ).
|
|
OO.88 | Co dělá a jak funguje add_cascade() ?
|
Funguje stejně jako okno.configure(menu = korenove_menu) (O.84) jen s tím rozdílem, že se používá na Záložkách nižšího řádu. Tzn. nejde použít na kořenové záložce. Tedy přiřazuje určitou Záložku do kaskády pod kořenovou záložku: korenova_zalozka.add_cascade(label = "něco", menu = podzalozka) . Zároveň přiřazuje widgetu tk.Menu text možností label . Widget tk.Menu totiž nemá možnost přidání textku.
|
|
OO.89 | Jaké druhé notací existují? |
|
|
OO.90 | Co řeší možnost weight při použití grafického manageru grid() ?
|
Řeší kolik zabere daný sloupec/řádka prostoru v defaultním stavu a při zvětšení. Pokud má například sloupec A váhu 1 a sloupec B váhu 2, bude mít sloupec B 2x větší šířku než sloupec A. Při zvětšování hlavního okna se pak bude tento poměr dodržovat. Pokud by měl sloupec B váhu 10, byl by 10x širší než sloupec A. | |
OO.91 | Mají pack() a grid() nějakou možnost pro border?
|
Závisí spíše na widgetu a není to tak robustní, jako v případě CSS. | Možná by šlo nasimulovat, tzn. udělat si simulační widget, který by v případě pack() možnostmi expand = True , a fill = "both" a v případě grid() a možnosti sticky = "nsew" vyplnil celý prostor a následně použít velky pady a padx , které by vytvořili pouze rám. Jenomže v pack() rozvržení se mi nemůžou widgety překrývat, tak pak tam nemohu vložit další pracovní.
|
OO.92 | Co je to notace? | Notace jsou metainformace, které svými znaky a systémem zvýrazňují syntax a sémantiku. | |
OO.93 | Lze zařídit, aby mi při přidělení vah v grafickém manageru grid() nemizely prvky při zmenšování hlavního okna?
|
Nepřímým způsobem je nastavení metody minsize(). Pokud má okno výchozí rozměry (okno.geometry("600x400") ), je možné nastavit minimální velikost na stejný rozměr (okno.minsize(600, 400) ).
|
|
OO.94 | Proč mi funguje skript i když tam mám překlepy? Například import tkinter as tik , ale níže volám hlavní okno jako tk.Tk() .
|
Pravděpodobně proto, že používám REPL a již jsem ve stejné seanci dříve nahrál tkinter do jmenného prostoru tk. Takže v novém importu provedu jen nový import do tik a tudíž mě bude fungovat jak volání tk.Tk() , tak tik.Tk() .
|
Pokud se něco chová nestandardně, je dobré konzoli promazat, nebo restartovat. |
OO.95 | Od čeho se odvozuje relativní šířka widgetu? | ||
OO.96 | Má absolutní pozicování geometrického manageru place( ) atribut anchor ?
|
Má, anchor lze využít jak v relativním, tak v absolutním pozicování.
|
|
OO.97 | Existuje obrácený atribut k aboveThis ?
|
Ano, belowThis .
|
|
OO.98 | Co je to flag variable a jak se chová? | Je to proměná s hodnotou Boolean, která označuje nějaký stav, ale není na něj přímo navázána. | |
OO.99 | Existuje nějaké doporučení jaký geometrický manager použít na co? | Není, ale pro jednoduší rozvržení se doporučují manager pack() a grid() .
|
|
OO.100 | Když je u place() jedna ze souřadnic zadána relativně a druhá absolutně, jedná se o relativní, nebo absolutní pozicování?
|
Absolutní. | |
OO.101 | Co dělá atribut uniform ?
|
||
OO.102 | Vykreslují se widgety na každém operačním systému jinak? | Ano, tkinter se snaží reprezentovat výchozí nastavení GUI každého operačního systému, aby to lépe fungovalo. | |
OO.103 | Jak odsadím widget zleva v grafickém manageru grid() (Debian)?
|
Závisí na celkovém designu, ale jde třeba přidat do sticky east (sticky = "e" ), to ho přisadí doprava a teoreticky odsadí zleva.
|
|
OO.104 | Co je to třída a jak vypadá? | Třída je něco jako šablona obsahující určitou část základních nastavení, které se dají následně natahovat do jiných objektů jako základ. Vytvářejí se tam, kde se něco repetitivně opakuje, aby se nemusel kód opakovat. | |
OO.105 | Co dělá funkce super() ?
|
||
OO.106 | Proč musí funkce sama sebe spouštět přes __init__() ?
|
||
OO.107 | Jak funguje create_rectangle() ?
|
Vytváří čtverec, kdy se do závorky zadají pozice horního levého a poté dolního pravého roku pozice. | |
OO.108 | Jaké má opoctatnění syntaxe znacka["text"] = vstupni_text namísto znacka.configure(text = vstupni_text) ?
|
Jde o to, že se běžně tímto způsobem volají hodnoty názvů ve slovníku. my_dict = {'key1': 'value1', 'key2': 'value2'}
print(my_dict['key1'])
value1 . Mohlo by to být i hodnota = my_dict["key1"] .
|
|
OO.109 | Odkud tk.StringVar() či tk.IntVar() získávají hodnoty, pokud neobsahují žádné parametry?
|
Získávají je z objektu, který má v hodnotě vlastnosti textvariable (případně u některých widgetů variable) stejný řetězec jako je název proměné těchto metod. Pokud např. máme:...
retezec_tlacitka = tk.StringVar()
tlacitko = ttk.Button( text = "Prostě tlačítko", textvariable = retezec_tlacitka)
...
StringVar() hodnotu v podobě řetězce z widgetu nebo proměnné tlacitko , protože je na ni napojena pomocí vlastnosti textvariable .
|
|
OO.110 | Které widgety mají vlastnost textvariable a které naopak používají vlastnost variable ?
|
textvariable:
variable:
|
|
OO.111 | Proč neposílá StringVar() na ttk.Radiobutton žádné hodnoty? Kód je následující:...
radio_var = tk.StringVar()
radio_1 = ttk.Radiobutton(okno, text = "Kulatý knoflík 1", variable = radio_var, value = "radio 1").pack()
radio_2 = ttk.Radiobutton(okno, text = "Kulatý knoflík 2", variable = radio_var, value = 2).pack()
...
|
||
OO.112 | Má metoda columnconfigure() a rowconfigure() možnost řazení z jiného směru? Default je zleva a zeshora.
|
Nemá, musela by se každá buňka obalit rámem metody pack a vysadit jinak. Pak by ale pozbývalo smyslu používat grid metodu a kód by byl moc složitý. | |
OO.113 | Jaký je rozdíl mezi absolutním a relativním pozicováním? | Rozdíl se projeví při změnách okna (pro widgety master), kdy při absolutním pozicování stojí widget stále na stejném místě, tzn. že se může schovat za hranu rámu okna, kdežto při relativním pozicování se mění a zůstává stále viditelný. | |
OO.114 | Jakých hodnot může nabývat vlastnost fill ?
|
Závisí v jakém kontextu se používá. Většinou definuje barvu (u metod, které vytvářejí tvar - např. create_line() ). Hodnoty jsou barvy anglicky v uvozovkách, tedy např. "red" , "blue" , "green" , atd. Nicméně v případě geometrického manageru pack() definuje směr kterým se danný widget rozšíří (hodnoty x , y , both , none - none je výchozí hodnotou).
|
|
OO.115 | Pokud je yview metoda, proč se za ní v zápise ttk.Scrollbar(okno, orient = "vertical", command = platno.yview) nepíš závorka?
|
||
OO.116 | Co je to set v tkinter.configure(yscrollcommand = scrollbar.set) ?
|
||
OO.117 | Jak funguje metoda bind() ?
|
Propojuje určitý typ události s funkcí. Obecný zápis je widget.bind(udalost, funkce) . Předdefinované typy událostí jsou řetězce, takže jsou v uvozovkách a jsou zvýrazněné špičatými závorkami (např. "<Button-1>" ). Většinou tedy snímají události z klávesnice, myši, ale mohou přijímat i určitý typ virtuálních událostí. Tyto události se mohou na různých operačních systémech lišit (například Linux systémy nemají událost <MouseWheel>, která zaznamenává obecně skrolování myší (na Windows nahoru i dolu). Místo toho rozeznává dvě události<Button-4> pro scrollování nahoru a <Button-5> pro scrollování dolů.
|
|
OO.118 | Jak funguje metoda yview_scroll() ?
|
Metoda definuje jakým způsobem se bude scrollovat, jestli po řádcích (atribut units), nebo po stránkách (pages). Prvním atributem je číslo, které určí o kolik takových řádků nebo stránek má widget poskočit. Nejčastěji se tak metoda váže na wedget Canvas, ale může se Vázat i na Text, nebo Listbox. | |
OO.119 | Co je to event.delta ?
|
Delta je hodnota která udává o kolik se posune objekt, při jednom otočení kolečka myši. Zároveň určuje i směr pozitivní, nebo negativné hodnotou. Tato hodnota se získává z yview_scroll() při skrolování. Jinak řečeno lambda funkcí přiřadíme k lokální proměnné event blok hodnot
( |
Tím že ve Windows funguje událost <MouseWheel> a v Linuxu ne, řešíme scrollování v Tkinteru jinak pro oba systémy. Ve Windows by byl výsek kódu následující:platno.bind("<MouseWheel>", lambda event: platno.yview_scroll(int(event.delta / 60), "units"))
.yview_scroll() umožňuje skrolovat a definuje způsob, získáváme z hodnoty události <MouseWheel> hodnotu sekce delta. Ta může být totiž jak plusová tak minusová, což nám zajistí, že se widget bude pohybovat nahoru a dolu a nemusíme kvůli tomu zřizovat další řádek kódu. Získanou hodnotu musíme převést na číslo a vydělíme ji například 60, čímž získáme 2 nebo -2. Plátno se tak v tomto případě posune o dvě řádky ("units") dolu, nebo nahoru (-2). Navíc byť na MacOs funguje stejná událost jako na Windows, je jiná hodnota a tudíž musíme použít jiné dělení (tedy nelze dělit 60).
V Linuxu se tento problém řeší dvoumi řádky kódu:platno.bind("<Button-5>", lambda event: platno.yview_scroll(1, "units"))
platno.bind("<Button-4>", lambda event: platno.yview_scroll(-1, "units"))
|
OO.120 | Lze přilepit událost ke kombinaci tlačítek na myši? | Lze, pokud chci například posunout plátno doprava, mohu operátorem + spojit dvě události do jedné. Následující kód posune plátno o jedno doprava, pokud bude stisknuto levé a pak pravé tlačítko:platno.bind("<Button-1>"+"<Button-3>", lambda event: platno.xview_scroll(1, "units"))
left_button_pressed = False
def left_button_press(event):
global left_button_pressed
left_button_pressed = True
def left_button_release(event):
global left_button_pressed
left_button_pressed = False
def right_button_release(event):
if left_button_pressed:
print("Right mouse button released while left button was pressed")
# Add your action here
root = tk.Tk()
frame = ttk.Frame(root, width=300, height=200)
frame.pack()
# Bind left button press and release events
frame.bind("<ButtonPress-1>", left_button_press)
frame.bind("<ButtonRelease-1>", left_button_release)
# Bind right button release event
frame.bind("<ButtonRelease-3>", right_button_release)
root.mainloop()
|
|
OO.121 | Jak zjistím názvy jednotlivých událostí pro tlačítka myši? | Například tak, že si nejprve ručně otestuji, jaké čísla mají jednotlivá kliknutí.button = ttk.Button(window, text = "Test your mouse in here. Check event name in stdout.")
button.pack(expand = True, fill = "both", padx = 10, pady = 10)
button.bind("<Button>", lambda event: print(event.num))
button.bind("<Button-1>", lambda event: print("povedlo se")) či button.bind("<Button-9>", lambda event: print("povedlo se")) ).
|
|
OO.122 | Co je to keysym a keycode ?
|
Keysym je symbol stisknuté klávesy a keycode její kód.
|
|
OO.123 | Co znamená zápis: <ButtonPress event state=Control|Mod2 num=5 x=310 y=216>?
|
Znamená, že byl stisknut Control (ButtonPressevent state=Control ), byl zapnut numlock (Mod2 ), bylo scrollováno kolečkem myši k sobě (num=5 ) - pouze Linux, a pozice kurzoru na daném widgetu byla na ve vzdálenosti 310 pixelů od nuly na ose x a 216 na ose y.
Podobně tak |
|
OO.124 | Jaká jsou čísla pro jednotlivá tlačítka myši a jakým názvům událostí to odpovídá? |
|
Zjištěno dle O.122 |
OO.125 | Jaké jsou parametry metody insert() ?
|
Pro každý widget se používají jiné parametry. Pro widgety Entry a Text se jedná o index a text. Index značí kam se má text vložit, a text je samotný text pro vložení.
Hodnotou parametru Hodnota pozice uvedená jedním číslem se dá použít pouze u jednořádkových widtegů jako je Ukázka využití čísla pro vložení konkrétního řetězce na pozici 0 u widgetu Entry: #Po kliknutí na tlačítko, se před číslo vloží mezinárodní předvolba 00420
def insert_number():
num = 00420
entry.insert(0, str(num))
# Create the main window
root = tk.Tk()
root.title("Vložení mezinárodní předvolby")
# Create an Entry widget
entry = tk.Entry(root)
entry.pack()
# Create a Button to trigger the insertion
button = tk.Button(root, text="Insert Number", command=insert_number)
button.pack()
...
text = tk.Text(okno)
#Zde se vloží textový řetězec
text.insert("1.0", f"Toto je test")
#Do výše uvedeného textového řetězce se u pátého znaku vloží TEST
text.insert("1.5", "TEST")
text.pack(expand=True, fill = "both")
...
end ) u widgetu Text:...
text = tk.Text(okno)
#Zde se vloží textový řetězec
text.insert("1.0", f"Toto je test")
#Na konec řádku vloží řetězec TEST
text.insert("end", " TEST")
text.pack(expand=True, fill = "both")
...
|
Indexy typu "řádek.znak" se uplatní i při vyjímání s využitím metody get(). Zde se dá těmito indexy zadat i rozsah:...
text = tk.Text(okno)
text.insert("1.0", f"Toto je test")
text.pack(expand=True, fill = "both")
#Vyjme slovo "je"
text_content = text.get('1.4','1.7')
print(text_content)
...
|
OO.126 | Jaké parametry má widget Treeview? | Obecný zápis je ttk.Treeview(kontajner, možnosti) , tedy ttk.Treeview(master = kontajner, moznost1 = hodnota, moznost2 = hodnota). Master je asi povinný. Možnosti jsou:
|
|
OO.127 | Lze u metody insert() zapsat parametry i se jmény?
|
Ano, lze. Je možný zápis s pojmenovanými parametry (.insert(index = 0, text = "00420") ) i bez nich (.insert(0, "00420") ).
|
|
OO.128 | Co znamená následující zápis: table.insert(parent = "", index = tk.END, values = (choice(jmena), choice(prijmeni))) ?
|
Metoda insert() vkládá nějaké hodnoty do widgetu Treeview. parent = "" znamená, že hodnoty se budou vkládat hned za kořenový sloupec. index = tk.END znamená, že každá nová řádka bude vložena na konec. Nakonec parameter values vkládá hodnoty do řádků. V něm je metoda choice() z knihovny random , která vybírá hodnoty nahodile z proměnných jmena a prijmeni . Tím, že jsou obě metody uzavřeny v klasických závorkách jedná se o ntici, která sytí dva sloupce.
|
|
OO.129 | Jak zjistím jakou mám Tkinter verzi? | from tkinter import TkVersion
print(TkVersion)
|
|
OO.130 | Jak rozumět tomuto kódu: platno.create_window((20,50), window = ttk.Button(okno, text = "Značka")) ?
|
Metoda create_window() vytváří ve widgetu Canvas okno, které umožňuje vkládat další widgety. Následujou koordináty umístění středu okna x a y , tedy 20 a 50 . Parametr window , za který se dá vložit jeden libovolný widget v tomto případě ttk.Button , do jehož závorky se samozřejmě vloží jeho parametry.
|
|
OO.131 | Má create_window() parameter background ?
|
Nemá. | |
OO.132 | Jaký je princip převodu kódu na třídu? | ||
OO.133 | Jak poznám, které atributy má konkrétní metoda? | Například na webu https://www.pythontutorial.net/tkinter. Nebo v komentářích některých py souborů (např. v /usr/lib/python3.11/tkinter/__init__.py )
|
|
OO.134 | Jak funguje metoda call() ?
|
Umožňuje spouštět Tcl příkazy z Pythonu. | |
OO.135 | Které widgety mají atribut command ?
|
|
|
OO.136 | Co dělá atribut menu (metody configure() )?
|
Přidává widget ttk.Menu do widgetu tk.Tk() .
|
|
OO.137 | Jak funguje možnost anchor u geometrického manageru place() ?
|
Je to bod kolem kterého se otáčí danný widget, tak že pozice mezi tímto bodem a levým horním okrajem parent okna musí sedět.
Defaultní je pozice v levém horním rohu, tedy |
Následující kód a komentáře v kódu celý koncept vysvětluji:#(Z knihovny tkinter) naimportuj modul tkinter a vlož ho do jmenného prostoru tk
import tkinter as tk
#Z knihovny tkinter naimportuj modul ttk (a vlož ho do jmenného prostoru ttk)
from tkinter import ttk
#Základní okno
okno = tk.Tk()
okno.title("Anchor")
okno.geometry("300x400")
okno.minsize(300, 400) #Definuje velikost okna pod kterou ho nejde zmenšit
znacka_1 = ttk.Label(okno, text = "widget 1", background = "orange")
znacka_2 = ttk.Label(okno, text = "widget 2", background = "pink")
znacka_3 = ttk.Label(okno, text = "widget 3", background = "aqua")
#Všechny níže uvedené widgety jsou umístěné 100 px od osy x a 200 px od osy y, respetive od levého horního rohu
#Rozdíl je jen v tom, ke kterému bodu widgetu to je vzdálenost:
znacka_1.place(x = 100, y = 200, width = 100, height = 50)#K levému hornímu
znacka_2.place(x = 100, y = 200, height = 100, anchor = "se")#K pravému dolnímu
znacka_3.place(x = 100, y = 200, anchor = "center")#Do centra
#Spuštění okna a čekání na události
okno.mainloop()
|
OO.138 | Které přednastavené názvy barev existují? | Je jich hodně, viz tento odkaz. | |
OO.139 | Jak zjistím, jestli mám staženou určitou komponentu? | Např. import customtkinter#název modulu
print("")
|
|
OO.140 | Jak nainstalovat v bashi customtkinter? | pip install customtkinter
|
|
OO.141 | Je customtkinter vhodný pro Linux? | Zdá se že ne. Zdá, se že vývojář řeší pouze Windows a MacOS. | |
OO.142 | Je customtkinter knihovna, nebo modul? | Knihovna | |
OO.143 | Proč jsou zaoblené rohy customtkinter na Linux tak hnusné? | Vývojář to zřejmě neřeší. | |
OO.144 | Co je to ttkbootstrap? | knihovna | |
OO.145 | Jaké themes existují v ttkbootstrap? | litera, minty, lumen, sandstone, yeti, pulse, united, morph, journal, darkly | |
OO.146 | Co zajišťuje metoda PhotoImage() ?
|
tk.PhotoImage(file=cesta k souboru) vytváří z obrázku objekt obrázku (<class 'tkinter.PhotoImage'> ), který je pak možné přes atribut image vložit do některých widgetů. Do widgetu tedy není možné rovnou vložit cestu k souboru, ale musí se vytvořit objekt obrázku, který se sem vloží:...
img = tk.PhotoImage(file = IMG_2154.JPG)
tlacitko = ttk.Button(okno, text = "Tlačítko", image = img)
tlacitko.pack()
....
|
|
OO.147 | Jak REPL pozná, kterou metodu využít, pokud natahuju více knihoven, které mají stejné názvy knihoven? | Nepozná, používá metody posledního importu, tedy toho co je nahoře nejníž. | |
OO.148 | Je běžné při natahování více knihoven uvádět u všech metod jmenný prostor? | Ano, jinak by mohlo dojít k problému. | |
OO.149 | Co je event.width a co to umí?
|
width je atribut z objektu vloženého do proměnné event . Tyto atributy jsou často svázány s událostmi metody bind() . Daný objekt může vypadat následovně:<Configure event x=143 y=0 width=457 height=400>
"<Configure>" , tedy událost, která často reaguje na změny polohy a velikosti určitého widgetu. Tato událost pak obsahuje čtyři atributy s hodnotami. width označuje šířku widgetu v určitém specifickovaném čase. Pokud chci tuto hodnotu následně přiřadit k nějaké proměnné, mohu ji vytěžit následujícím způsobem:moje_promena_sirky = event.width
|
Pro zobrazení objektu dané události, lze použít následující zobecněný kód: widget.bind("<udalost>", lambda objekt: print(objekt)) .
Konkrétně by to tedy mohlo vypadat takto:import tkinter as tk
...
okno = tk.Tk()
okno.geometry("600x400")
...
canvas = tk.Canvas(okno, background = "green", bd = 0, highlightthickness = 0, relief = "ridge")
canvas.grid(column = 1, columnspan = 3, row = 0, sticky = "nsew")
canvas.bind("<Configure>", lambda event: print(event))
<Configure event x=143 y=0 width=457 height=400>.
|
OO.150 | Co dělá canvas.create_image() ?
|
Přidá obrázek do widgetu Canvas. | |
OO.151 | Widgety se při změnách velikosti okna pomalu překreslují, takže je vidět po stranách barevný podklad. Jak se toho zbait? | ||
OO.152 | Má metoda canvas.create_image() možnost anchor = "center" ?
|
||
OO.153 | Jaké jsou atributy metody canvas.create_image() ?
|
||
OO.154 | Co dělá metoda canvas.create_window() ?
|
Vytváří widget window, který do sebe umožňuje vkládat další widgety a tím se mohou dostat různé widgety na Canvas. | |
OO.155 | Jak funguje atribut window , metody canvas.create_window() ?
|
||
OO.156 | Jak se liší argumenty self a parent , kdy je self hodnotou master a kdy argumentem?
|
||
OO.157 | Co je to atribut parent a kde se používá?
|
Parent ve třídě je zástupným parametrem pro hodnotu odesílanou z globálu. Hodnotou může být okno, tedy hlavní okno, ale i rám. | |
OO.158 | Jaký je rozdíl mezi použitím podtržítka (_ ) v loopu a dvojitéhopodtržítka (__ )?
|
||
OO.159 | Co to je rekurze? | Technika, kdy funkce volá sebe sama, aby získala výsledek. | |
OO.160 | Jakým způsobem fungují poziční argumenty u tříd? | ||
OO.161 | Jak se zobrazí zdrojový kód ttk.Frame? | Nejprve je potřeba si uvědomit, že i samotný ttk.Frame může dědit kód od nadřazených tříd. K tomu bysme ostatně došli, kdybysme si vypsali jeho kód. Strom dědičností je následující:
Pro vytištění kódu ttk.Frame můžeme použít následný kód:import inspect
from tkinter import ttk
zdrojovy_kod = inspect.getsource(ttk.Frame)
print(zdrojovy_kod)
import inspect
import tkinter
from tkinter import ttk
import subprocess
#Získá kódy jednotlivých tříd
zdrojovy_kod_1 = inspect.getsource(ttk.Frame)
zdrojovy_kod_2 = inspect.getsource(ttk.Widget)
zdrojovy_kod_3 = inspect.getsource(tkinter.Widget)
zdrojovy_kod_4 = inspect.getsource(tkinter.BaseWidget)
zdrojovy_kod_5 = inspect.getsource(tkinter.Misc)
zdrojovy_kod_6 = inspect.getsource(tkinter.Pack)
zdrojovy_kod_7 = inspect.getsource(tkinter.Place)
zdrojovy_kod_8 = inspect.getsource(tkinter.Grid)
#Vytiskne ttk.Frame až tkinter.Misc do konzole
#print(f"{zdrojovy_kod_5}\n {zdrojovy_kod_4}\n {zdrojovy_kod_3}\n {zdrojovy_kod_2}\n {zdrojovy_kod_1}")
#Vytiskne rovnocené rodičovské třídy ke třídě tkinter.Widget do stdout
#print(f"{zdrojovy_kod_8}\n {zdrojovy_kod_7}\n {zdrojovy_kod_6}")
#Vytvoří dva txt soubory s kódem tříd uspořádaných za sebou
with open('ttkFrame_to_tkMisc.txt', 'w') as file:
file.write(f"{zdrojovy_kod_5}\n {zdrojovy_kod_4}\n {zdrojovy_kod_3}\n {zdrojovy_kod_2}\n {zdrojovy_kod_1}")
with open('tkWidget_parent_classes.txt', 'w') as file:
file.write(f"{zdrojovy_kod_8}\n {zdrojovy_kod_7}\n {zdrojovy_kod_6}")
#A tyto dva soubory pak mohu rovnou otevřít
subprocess.run(['open', 'ttkFrame_to_tkMisc.txt'])
subprocess.run(['open', 'tkWidget_parent_classes.txt'])
|
|
OO.162 | Jak se vloží proklikávatelná ikona, tj. obrázek? | ||
OO.163 | Může mít tlačítko na pozadí obrázek? | ||
OO.164 | Co umí a dělá filedialog? | ||
OO.165 | Má ttk.spinbox metodu get() ?
|
Ano. | |
OO.166 | Proč atribut underline z ttk.Label má jednou hodnotu číslo a podruhé bool? | ||
OO.167 | Které widgety mohou mít vertikální orientaci? |
|
Nicméně například i tlačítko lze přinutit k vertikálnosti a to prostřednictví geometrického manageru grid a zadání přesahu přes několik řádek. Například: checker_button.grid(column = 0, row = 0, rowspan = 6, sticky = "nsew") .
|
OO.168 | |||
OO.169 |
Chyby a řešení
[editovat]Při zapisování chybových hlášení je dobré zapsat i část kódu, která chybu způsobuje.
Č. | Kód | Chyba | Odstraňování chyby | Vysvětlení | Poznámky |
---|---|---|---|---|---|
CHŘ.1 | import tkinter as tk
#Výchozí okno
okno = tk.Tk()
okno.title("Prostě vokno")
okno.geometry("500x500")
#Widgety
promena_text = tk.Text(master = window)
promena_text.pack()
#Spouštěcí code
okno.mainloop()
|
File "<string>", line 1, in <module>
NameError: name 'promena_text' is not defined
|
ChatGPT odhalili, že volám neexistující master. Hodnota nemá být window, ale okno. | ||
CHŘ.2 | Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
File "<string>", line 2, in read_and_insert_default
AttributeError: 'Label' object has no attribute 'get'
|
Widget Label nemá metodu get() , která byla v kodu použitá na druhém řádku ve funkci "read_and_insert_default".
|
|||
CHŘ.3 | Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
File "<string>", line 4, in insert_default
File "/usr/lib/python3.10/tkinter/__init__.py", line 1686, in __setitem__
self.configure({key: value})
File "/usr/lib/python3.10/tkinter/__init__.py", line 1675, in configure
return self._configure('configure', cnf, kw)
File "/usr/lib/python3.10/tkinter/__init__.py", line 1665, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-pady"
|
Používat vlastnost padding .
|
Vypadá to jakoby metoda configure() na widgetu Label neměla možnst "pady", nicméně na diskusní stránce Pythonu mi řekli, že možnosti configure() jsou totožené s možnostmi widgetu. O.10 | ||
CHŘ.4 | Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
File "<string>", line 5, in insert_default
NameError: name 'yellow' is not defined
|
Protože hodnotu konfigurační možnosti mám zadávat jako řetězec, tedy v uvozovkách. Jinak je to chápáno jako proměnná. Tedy znacka["background"] = "yellow" , ne znacka["background"] = yellow .
|
|||
CHŘ.5 | Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
File "<string>", line 2, in uncheck_checkbutton_and_print_its_value
AttributeError: 'str' object has no attribute 'set'
|
||||
CHŘ.6 | ...
okno.bind("<KeyPress>", lambda: print("Něco bylo stisknuto"))
...
|
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
TypeError: <lambda>() takes 0 positional arguments but 1 was given
|
...
okno.bind("<KeyPress>", lambda event: print("Něco bylo stisknuto"))
...
|
Tím, že metoda widget.bind() posílá do lambdy nějaká data, je potřeba je poslat do proměnné event . Kdybych do lambdy žádná data neposílal, proměnou nepotřebuji. Např.: tlacitko3 = ttk.Button(master = okno, text = "Pokusne tlacitko", command = lambda: print("čau")).pack() Zde je lambda navázána na atribut command a nejsou do ni posílána žádná data.
|
|
CHŘ.7 | ...
text.bind("<FocusIn>"+"<Shift>"+"<MouseWheel>", lambda vybrano: print("Mousewheel"))
...
|
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.10/tkinter/__init__.py", line 1421, in bind
return self._bind(('bind', self._w), sequence, func, add)
File "/usr/lib/python3.10/tkinter/__init__.py", line 1375, in _bind
self.tk.call(what + (sequence, cmd))
_tkinter.TclError: bad event type or keysym "Shift"
|
Protože v Tkinteru nelze spárovat výstupy různých eventů.
|
||
CHŘ.8 | ...
combo = ttk.Combobox(master = okno).pack()
combo["values"] = polozky
...
|
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: 'NoneType' object does not support item assignment
|
...
combo = ttk.Combobox(master = okno)
combo.pack()
combo["values"] = polozky
...
|
Jde o to, že se do proměnné zapisuje poslední část řetězce, tedy v tomto případě pouze pack() , proto pack() musí být na separátním řádku mimo řetězec.
|
|
CHŘ.9 | ...
polozky = ("Zmrzka", "Pizza", "Mrkev")
combo = ttk.Combobox(master = okno)
combo["items"] = polozky
...
|
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.10/tkinter/__init__.py", line 1686, in __setitem__
self.configure({key: value})
File "/usr/lib/python3.10/tkinter/__init__.py", line 1675, in configure
return self._configure('configure', cnf, kw)
File "/usr/lib/python3.10/tkinter/__init__.py", line 1665, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-items"
|
...
polozky = ("Zmrzka", "Pizza", "Mrkev")
combo = ttk.Combobox(master = okno)
combo["values"] = polozky
...
|
Hodnoty v závorkách jsou pro ttk.Combobox předdefinovány, takže člověk musí vložit hodnotu values .
|
|
CHŘ.10 | stredova_znacka = ttk.Label(okno, text = "Středová značka", background = "pink")
stredova_znacka.pack(x = 0, y = 0, width = 200, height = 200, anchor = "center")
|
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.10/tkinter/__init__.py", line 2425, in pack_configure
self.tk.call(
_tkinter.TclError: bad option "-x": must be -after, -anchor, -before, -expand, -fill, -in, -ipadx, -ipady, -padx, -pady, or -side
|
stredova_znacka = ttk.Label(okno, text = "Středová značka", background = "pink")
stredova_znacka.place(x = 0, y = 0, width = 200, height = 200, anchor = "center")
|
Použit chybný geometrický manager. Má být place() , byl pack() .
|
|
CHŘ.11 | Zřejmě se to týká, tohoto kódu:znacka3 = ttk.Label(okno, text = "Značka 3", background = "blue").place(
x = 70, y = 110, width = 200, height = 150
)
tlacitko3 = ttk.Button(okno, text = "Tlačítko 3", command = lambda: znacka3.lower()).place(
rely = 1, relx = 0.6, anchor = "se"
)
|
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
File "<string>", line 1, in <lambda>
AttributeError: 'NoneType' object has no attribute 'lower'
|
znacka3 = ttk.Label(okno, text = "Značka 3", background = "blue")
znacka3.place( x = 70, y = 110, width = 200, height = 150)
ttk.Button(okno, text = "Tlačítko 3", command = lambda: znacka3.lower()).place(rely = 1, relx = 0.6, anchor = "se")
|
Šlo by to například řešit takto. Jde o to, že pokud geometrický manager place() posílá hodnotu do promené značka, nevysílá ve skutečnosti nic. Proto nelze v následujícím kroku provést na hodnotě NoneType metodu lower() . Když se ale geometrický manager posune na novou řádku a pouze se aplikuje na proměnou znacka3 , tak to jde. Protože widget generuje proměnou konkrétního widgetu (<class 'tkinter.ttk.Label'> ) a na tomto typu hodnoty lze provést jak umístění (prostřednictvím place() ), tak aplikovat metodu lower() .
Pokud dále nepracuju s tlačítkem 3, nepotřebuji vytvářet promenou To jaký typ hodnoty mi daný kód generuje lze zjistit pomocí |
|
CHŘ.12 | import tkinter as tk
from tkinter import ttk
...
img = tk.PhotoImage(file = "/home/juan/~/kabrinec4d.jpg")
...
|
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.10/tkinter/__init__.py", line 4103, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "/usr/lib/python3.10/tkinter/__init__.py", line 4048, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "/home/juan/~/kabrinec4d.jpg"
|
import tkinter as tk
from tkinter import ttk
...
img = tk.PhotoImage(file = "/home/juan/~/kabrinec4d.pgm")
...
|
||
CHŘ.13 | import tkinter as tk
from tkinter import ttk
class Segment(ttk.Frame):
def __init__(self, parent, text_znacky, text_tlacitka):
super().__init__(master = parent)
#Vytvoření gridu
self.rowconfigure(0, weight = 1)
self.columnconfigure((0,1,2), weight = 1, uniform = "a")
ttk.Label(self, text = text_znacky).grid(row = 0, column = 0, sticky = "nsew")
ttk.Button(self, text = text_tlacitka).grid(row = 0, column = 1, sticky = "nsew")
self.pack(expand = True, fill = "both", padx = 5, pady = 2)
self.mensi_segment()
def mensi_segment(self):
kontys = ttk.Frame()
kontys.grid(row = 0, column = 2)
vstup = ttk.Entry(kontys, text = "Vstup").pack()
tlacitko = ttk.Button(kontys, text = "Tlačítko 3").pack()
#Okno
okno = tk.Tk()
okno.title("Mnohočetný otisk jedné třídy")
okno.geometry("400x600")
#Widgety
Segment(okno, "Značka", "Tlačítko")
Segment(okno, "Značka 2", "Tlačítko 2")
Segment(okno, "Značka 3", "Tlačítko 3")
Segment(okno, "Značka 4", "Tlačítko 4")
Segment(okno, "haf", "haf")
#Spuštění okna a čekání na události
okno.mainloop()
|
Traceback (most recent call last):
File "/home/juan/~/025 kombinace oop a funkcniho pristupu.py", line 43, in <module>
Segment(okno, "Značka", "Tlačítko")
File "/home/juan/~/025 kombinace oop a funkcniho pristupu.py", line 21, in __init__
self.mensi_segment()
File "/home/juan/~/025 kombinace oop a funkcniho pristupu.py", line 25, in mensi_segment
kontys.grid(row = 0, column = 2)
File "/usr/lib/python3.10/tkinter/__init__.py", line 2522, in grid_configure
self.tk.call(
_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack
|
|||
CHŘ.14 | |||||
CHŘ.15 |
Související otázky
[editovat]Otázky, které se netýkají hlavního předmětu, ale souvisí s ním. Zvažte zapsání dotazu a odpovědi na stránku, která je tématu bližší (seznam dostupných témat).
Č. | Otázka | Detailní popis, fotografie, video | Odpověď | Poznánky |
---|---|---|---|---|
1 | Jak se vypočte poměr stran určitého objektu? | U objektů, které mají více stran, se poměr vztahuje vždy ke konkrétní straně. Obdélník, nebo obrázek o poměru 16:9 má jinou orientaci, než obdélník o poměru stran 9:16. Poměry u jednotlivých obrazců lze vyjádřit i následovně:
| ||
2 | Jaký je vrozreček pro zoom objektu? | |||
3 | Jak myslí matematiky? Představuje si nějaké objekty? | |||
4 | Je matematika jazyk? |