Hlavní navigace

Grafické uživatelské rozhraní v Pythonu: použití dialogových oken v knihovně Tkinter

Pavel Tišnovský

V posledním článku o knihovně Tkinter v Pythonu si ukážeme, jak se vytváří modální i nemodální dialogová okna. Bude se jednat jak o standardní dialogy (výběr souboru atd.), tak i o dialogy definované vývojářem.

Obsah

1. Základy práce s dialogovými okny

2. Modální a nemodální dialogová okna

3. Standardní dialogová okna pro zobrazení zprávy uživateli

4. První demonstrační příklad: zobrazení informačních dialogů s tlačítkem Ok

5. Standardní dialogová okna s otázkou (Ok/Cancel, Yes/No, Ok/Retry)

6. Druhý demonstrační příklad: dialogová okna s otázkou položenou uživateli

7. Konfigurace standardních dialogových oken podle přání programátora

8. Třetí demonstrační příklad: úprava dialogového okna vyvolaného funkcí askquestion

9. Programátorem definovaná dialogová okna

10. Čtvrtý příklad – jednoduché okno pro vyplnění informací o uživateli

11. Vylepšení dialogového okna – nastavení modality, nastavení implicitně vybraného tlačítka a použití kláves pro uzavření dialogu

12. Pátý příklad – integrace vylepšeného dialogového okna

13. Další standardní dialogová okna: otevření dokumentu a uložení dokumentu pod novým jménem

14. Šestý příklad – použití dialogového okna pro otevření dokumentu

15. Sedmý příklad – dialog pro uložení dokumentu pod novým jménem

16. Osmý příklad – výběr barvy z palety

17. Repositář s demonstračními příklady

18. Odkazy na Internetu

1. Základy práce s dialogovými okny

Dialogová okna jsou v grafických uživatelských prostředích využívána poměrně často. Tyto prvky grafického uživatelského rozhraní vlastně vznikly postupnou evolucí. První aplikace s GUI většinou obsahovaly jednoduché drop-down menu, které se dále nevětvilo. Se zvyšující se složitostí aplikací se menu začalo postupně větvit až do okamžiku, v němž se překročil určitý bod komplexnosti, kdy se práce s menu stávala neefektivní. V tomto bodě se začaly vytvářet (většinou modální) dialogová okna, která na své ploše sdružovala několik ovládacích prvků. Jak však z každodenní zkušenosti víme, i dialogová okna se brzy zaplnila a pro jejich zjednodušení (resp. rozčlenění) se v dnešní době používá několik řešení: okna se záložkami (notebook, tabbed notebook), ikony po straně okna sdružující spolu související operace, nebo postupné procházení několika dialogy ve stylu „wizardů“.

Kromě zvládnutí vyšší komplexnosti aplikací hrají dialogová okna i další roli – pomáhají totiž standardizovat některé společné části aplikací. Například pro otevření souboru, uložení souboru, tisk dokumentu nebo výběr barvy je možné (a velmi vhodné) použít standardní dialog dodávaný s GUI systémem. Do jaké míry se tento systém standardizace využívá, čtenář patrně vidí na svém desktopu sám: určitá míra standardizace je patrná, také je však zřejmé, že mnohé aplikace využívají jiné GUI knihovny, o míchání několika desktopových prostředích ani nemluvě (to zdaleka není pouze problém GNU softwaru, „lidová tvořivost“ je vidět i na komerčních programech).

2. Modální a nemodální dialogová okna

Při práci s dialogovými okny rozlišujeme dialogy modální a nemodální. Modální dialogy převezmou řízení celé aplikace a nedovolí uživateli pokračovat v práci, dokud nevybere z dialogu nějaký příkaz. Naproti tomu jsou nemodální okna zobrazena „paralelně“ s aplikací a neblokují vstup do aplikace (kromě toho, že jsou většinou zobrazena nad aplikací). Vzhledem k tomu, že jsou modální okna programátorsky jednodušeji zvládnutelná, používají se častěji, a to i v těch případech, kdy modální okno uživatele zdržuje či mu komplikuje práci. Typickým příkladem je dialog pro vyhledávání (například řetězců), který by měl být prakticky vždy nemodální, ale mnohé aplikace ho implementují jako dialog modální.

V každém případě však knihovna Tkinter umožňuje použití několika standardních dialogů pro nejčastěji používané činnosti se soubory a dokumenty. Kromě toho je možné pomocí jednoho příkazu vytvořit i vlastní dialogové okno, složitější dialogová okna se vytváří podobně jako každé jiné okno (pouze se musí nastavit modalita, pokud je vyžadována).

3. Standardní dialogová okna pro zobrazení zprávy uživateli

V modulu tkinter.messagebox najdeme několik funkcí sloužících pro vytvoření dialogového okna, v němž se zobrazí zpráva uživateli společně s tlačítkem OK. Kromě vlastní zprávy je možné specifikovat i titulek okna (ten se může zobrazit v seznamu oken). Jednotlivé funkce se od sebe odlišují tím, jaká ikona je v dialogovém oknu zobrazena:

Funkce Ikona
showinfo()
showwarning()
showerror()

Poznámka: ve skutečnosti se mohou ikony na různých systémech odlišovat, jejich význam však bude odpovídat typu dialogového okna. Výše zobrazená trojice ikon byla získána na Linuxu s Fluxboxem.

4. První demonstrační příklad: zobrazení informačních dialogů s tlačítkem Ok

V dnešním prvním demonstračním příkladu se zobrazí okno s tlačítky, po jejichž stisku se vykreslí příslušný standardní informační dialog:

messagebox.showinfo("Title", "Text"))
 
messagebox.showwarning("Title", "Text"))
 
messagebox.showerror("Title", "Text"))

Obrázek 1: Informační dialog vytvořený funkcí messagebox.showinfo().

Na začátku programu nezapomeňte na následující import:

from tkinter import messagebox

Obrázek 2: Informační dialog vytvořený funkcí messagebox.showwarning().

Úplný zdrojový kód prvního příkladu vypadá takto:

#!/usr/bin/env python
 
import tkinter
from tkinter import ttk
from tkinter import messagebox
import sys
 
 
def exit():
    sys.exit(0)
 
 
root = tkinter.Tk()
 
 
infoButton = tkinter.Button(root, text="Info box",
                            command=lambda: messagebox.showinfo(
                                "Title",
                                "Text"))
 
warningButton = tkinter.Button(root, text="Warning box",
                               command=lambda: messagebox.showwarning(
                                   "Title",
                                   "Text"))
 
errorButton = tkinter.Button(root, text="Error box",
                             command=lambda: messagebox.showerror(
                                 "Title",
                                 "Text"))
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
infoButton.pack(fill=tkinter.BOTH)
warningButton.pack(fill=tkinter.BOTH)
errorButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

Obrázek 3: Informační dialog vytvořený funkcí messagebox.showerror().

5. Standardní dialogová okna s otázkou (Ok/Cancel, Yes/No, Ok/Retry)

Knihovna Tkinter obsahuje i několik standardních dialogových oken, v nichž se po uživateli vyžaduje reagovat na položenou otázku, popř. na nějaký stav aplikace (nepodařený tisk atd.) stiskem jednoho z nabízených tlačítek. Tato dialogová okna jsou opět vyvolána funkcemi, které nalezneme v modulu tkinter.messagebox:

Yes+No
Funkce Ikona Zobrazená tlačítka
askokcancel() OK+Cancel
askretrycancel() Retry+Cancel
askyesno()
askquestion() ve výchozím nastavení Yes+No

Poznámka: v sedmé kapitole je popsáno, jakým způsobem je možné dialogy nakonfigurovat, aby se zobrazily ty ikony a tlačítka, která programátor v daný okamžik vyžaduje.

Obrázek 4: Dialog  otázkou vytvořený funkcí messagebox.askokcancel().

6. Druhý demonstrační příklad: dialogová okna s otázkou položenou uživateli

Druhý demonstrační příklad se podobá příkladu prvnímu, ovšem používáme v něm standardní dialogová okna s otázkou, na kterou uživatel musí odpovědět. Po spuštění příkladu si vyzkoušejte, jaké návratové hodnoty z těchto modálních oken získáme (hodnoty se přímo tisknou na standardní výstup, takže je to velmi jednoduché).

Obrázek 5: Dialog  otázkou vytvořený funkcí messagebox.askretrycancel().

Následuje výpis zdrojového kódu dnešního druhého demonstračního příkladu:

#!/usr/bin/env python
 
import tkinter
from tkinter import ttk
from tkinter import messagebox
import sys
 
 
def exit():
    sys.exit(0)
 
 
def showOkCancelMessageBox():
    print(messagebox.askokcancel("Otázečka na závěr",
                                 "Skutečně, ale skutečně ukončit program?"))
 
 
def showRetryCancelMessageBox():
    print(messagebox.askretrycancel("Chyba při tisku",
                                    "Opakovat tisk?"))
 
 
def showYesNoMessageBox():
    print(messagebox.askyesno("Otázečka na závěr",
                              "Skutečně, ale skutečně ukončit program?"))
 
 
def showQuestionMessageBox():
    print(messagebox.askquestion("Otázečka na závěr",
                                 "Provést zálohu?"))
 
 
root = tkinter.Tk()
 
showOkCancelButton = tkinter.Button(root, text="Show Ok/Cancel message box",
                                    command=showOkCancelMessageBox)
 
showRetryCancelButton = tkinter.Button(root, text="Show Retry/Cancel box",
                                       command=showRetryCancelMessageBox)
 
showYesNoButton = tkinter.Button(root, text="Show Yes.No box",
                                 command=showYesNoMessageBox)
 
showQuestionButton = tkinter.Button(root, text="Show question box",
                                    command=showQuestionMessageBox)
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
showOkCancelButton.pack(fill=tkinter.BOTH)
showRetryCancelButton.pack(fill=tkinter.BOTH)
showYesNoButton.pack(fill=tkinter.BOTH)
showQuestionButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

Obrázek 6: Dialog  otázkou vytvořený funkcí messagebox.askyesno().

Obrázek 7: Dialog  otázkou vytvořený funkcí messagebox.askquestion().

7. Konfigurace standardních dialogových oken podle přání programátora

Ve skutečnosti je možné dialogová okna upravovat pomocí nepovinných (pojmenovaných) parametrů, především pak:

Parametr Význam Možné hodnoty
type typ dialogu ABORTRETRYIGNORE, OK, OKCANCEL, RETRYCANCEL, YESNO, YESNOCANCEL
default které tlačítko bude implicitně vybráno ABORT, RETRY, IGNORE, OK, CANCEL, YES, NO
icon jméno ikony ERROR, INFO, QUESTION, WARNING

Typicky se pro úpravy používá „univerzální“ dialog vyvolaný funkcí askquestion():

messagebox.askquestion("Otázečka na závěr",
                       ("Provést zálohu?\n"
                        "Naformátovat disk?\n"
                        "Kontaktovat NSA?"),
                       icon=messagebox.ERROR,
                       type=messagebox.ABORTRETRYIGNORE)

8. Třetí demonstrační příklad: úprava dialogového okna vyvolaného funkcí askquestion

V dnešním třetím demonstračním příkladu je ukázán způsob zobrazení dialogového okna s trojicí tlačítek Abort, Retry a Ignore. V okně se navíc kromě zprávy zobrazí i ikona představující chybu, která na Linux s Fluxboxem vypadá jako značka zákazu vjezdu do jednosměrky:

Obrázek 8: Dialog  otázkou vytvořený funkcí messagebox.askquestion(), v níž jsou umístěna uživatelem zvolená tlačítka i ikona.

Následuje výpis zdrojového kódu dnešního třetího demonstračního příkladu:

#!/usr/bin/env python
 
import tkinter
from tkinter import ttk
from tkinter import messagebox
import sys
 
 
def exit():
    sys.exit(0)
 
 
def showQuestionMessageBox():
    print(messagebox.askquestion("Otázečka na závěr",
                                 ("Provést zálohu?\n"
                                  "Naformátovat disk?\n"
                                  "Kontaktovat NSA?"),
                                 icon=messagebox.ERROR,
                                 type=messagebox.ABORTRETRYIGNORE))
 
 
root = tkinter.Tk()
 
showQuestionButton = tkinter.Button(root, text="Show question box",
                                    command=showQuestionMessageBox)
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
showQuestionButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

9. Programátorem definovaná dialogová okna

Standardní dialogová okna samozřejmě nemohou vyhovovat ve všech případech, takže si vývojáři mnohdy musí chování i vzhled dialogových oken naprogramovat. Jeden z možných způsobů je popsán v následujícím textu. Nejprve budeme deklarovat novou třídu odvozenou od třídy tkinter.Toplevel, která představuje jakékoli okno. V konstruktoru zavoláme konstruktor předka:

class Dialog(tkinter.Toplevel):
 
    def __init__(self, parent):
        tkinter.Toplevel.__init__(self, parent)

Následně vytvoříme widgety, které budou v dialogovém oknu zobrazeny. Pro jednoduchost se bude jednat o dvojici vstupních polí, tlačítko pro potvrzení dialogu a dvě pomocná návěští. Po stisku tlačítka OK se zavolá metoda ok():

        label1 = tkinter.Label(self, text="First name")
        label2 = tkinter.Label(self, text="Surname")
         
        self.entryFirstName = tkinter.Entry(self)
        self.entrySurname = tkinter.Entry(self)
         
        okButton = tkinter.Button(self, text="OK", command=self.ok)

Posléze widgety umístíme do dialogového okna způsobem, který již dobře známe:

        label1.grid(row=1, column=1, sticky="W", padx=5, pady=5)
        label2.grid(row=2, column=1, sticky="W", padx=5, pady=5)
        self.entryFirstName.grid(row=1, column=2, sticky="WE")
        self.entrySurname.grid(row=2, column=2, sticky="WE")
         
        okButton.grid(row=4, column=2, sticky="W")

Druhá metoda bude reagovat na stisk tlačítka OK:

    def ok(self):
        print("first name:", self.entryFirstName.get())
        print("surname:", self.entrySurname.get())
        self.destroy()

Zobrazení dialogu navážeme na nějaké tlačítko zobrazené v hlavním okně:

showDialogButton = tkinter.Button(root, text="Show dialog",
                                  command=lambda: Dialog(root))

Obrázek 9: Dialogové okno vytvořené programátorem.

10. Čtvrtý příklad – jednoduché okno pro vyplnění informací o uživateli

Třídu Dialog popsanou v předchozí kapitole použijeme v dnešním čtvrtém demonstračním příkladu, jehož zdrojový kód vypadá následovně:

#!/usr/bin/env python
 
import tkinter
from tkinter import ttk
from tkinter import messagebox
import sys
 
 
def exit():
    sys.exit(0)
 
 
class Dialog(tkinter.Toplevel):
 
    def __init__(self, parent):
        tkinter.Toplevel.__init__(self, parent)
 
        label1 = tkinter.Label(self, text="First name")
        label2 = tkinter.Label(self, text="Surname")
 
        self.entryFirstName = tkinter.Entry(self)
        self.entrySurname = tkinter.Entry(self)
 
        okButton = tkinter.Button(self, text="OK", command=self.ok)
 
        label1.grid(row=1, column=1, sticky="W", padx=5, pady=5)
        label2.grid(row=2, column=1, sticky="W", padx=5, pady=5)
        self.entryFirstName.grid(row=1, column=2, sticky="WE")
        self.entrySurname.grid(row=2, column=2, sticky="WE")
 
        okButton.grid(row=4, column=2, sticky="W")
 
    def ok(self):
        print("first name:", self.entryFirstName.get())
        print("surname:", self.entrySurname.get())
        self.destroy()
 
 
root = tkinter.Tk()
 
showDialogButton = tkinter.Button(root, text="Show dialog",
                                  command=lambda: Dialog(root))
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
showDialogButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

11. Vylepšení dialogového okna – nastavení modality, nastavení implicitně vybraného tlačítka a použití kláves pro uzavření dialogu

Dialogové okno vytvořené v rámci předchozího příkladu se vlastně nechová podle očekávání – není modální, lze ho otevřít vícekrát (schválně si to vyzkoušejte), nelze použít klávesy Enter a Esc pro potvrzení volby resp. po opuštění okna atd. Zkusme tedy nyní chování okna vylepšit.

Nejprve svážeme dialogové okno se svým předkem (ten je předán konstruktoru v parametru nazvaném parent). Díky tomu by se dialogové okno nemělo ukázat v seznamu oken:

# dialog bude svazan se svym predkem
# (nemel by se zobrazit v seznamu oken)
self.transient(parent)

Dále zajistíme chování dialogového okna ve chvíli, kdy uživatel stlačí ikonu pro uzavření okna (jak vypadá, je věcí správce oken). Můžeme pokus o uzavření dialogu ignorovat, naprogramovat si vlastní akci nebo ho akceptovat:

# chovani pri pokusu o zavreni okna pres "x" (lze zakazat)
self.protocol("WM_DELETE_WINDOW", self.destroy)

V následujícím kroku zajistíme, že první vstupní pole získá fokus (uživatel do něj nemusí klikat myší) a současně nebude možné, aby předek fokus převzal – jinými slovy nebude možné se přepnout na hlavní okno aplikace:

# predek neziska fokus
self.grab_set()
 
# ziskani fokusu
self.entryFirstName.focus_set()

Poslední úprava spočívá v tom, že se po stisku klávesy Enter (zde z historických důvodů nazývané Return) zavolá metoda ok() a po stisku klávesy Esc metoda destroy(). Stisk Enteru je tedy shodný se stiskem widgetu OK zatímco stisk Esc s uzavřením dialogu:

# implicitni chovani klaves Return/Enter a Escape
self.bind("<Return>", lambda event: self.ok())
self.bind("<Escape>", lambda event: self.destroy())

12. Pátý příklad – integrace vylepšeného dialogového okna

Vylepšená třída Dialog je použita v pátém příkladu:

#!/usr/bin/env python
 
import tkinter
from tkinter import ttk
from tkinter import messagebox
import sys
 
 
def exit():
    sys.exit(0)
 
 
class Dialog(tkinter.Toplevel):
 
    def __init__(self, parent):
        tkinter.Toplevel.__init__(self, parent)
 
        # dialog bude svazan se svym predkem
        # (nemel by se zobrazit v seznamu oken)
        self.transient(parent)
 
        label1 = tkinter.Label(self, text="First name")
        label2 = tkinter.Label(self, text="Surname")
 
        self.entryFirstName = tkinter.Entry(self)
        self.entrySurname = tkinter.Entry(self)
 
        okButton = tkinter.Button(self, text="OK", command=self.ok)
 
        label1.grid(row=1, column=1, sticky="W", padx=5, pady=5)
        label2.grid(row=2, column=1, sticky="W", padx=5, pady=5)
        self.entryFirstName.grid(row=1, column=2, sticky="WE")
        self.entrySurname.grid(row=2, column=2, sticky="WE")
        okButton.grid(row=4, column=2, sticky="W")
 
        # chovani pri pokusu o zavreni okna pres "x" (lze zakazat)
        self.protocol("WM_DELETE_WINDOW", self.destroy)
 
        # predek neziska fokus
        self.grab_set()
 
        # implicitni chovani klaves Return/Enter a Escape
        self.bind("<Return>", lambda event: self.ok())
        self.bind("<Escape>", lambda event: self.destroy())
 
        # ziskani fokusu
        self.entryFirstName.focus_set()
 
    def ok(self):
        print("first name:", self.entryFirstName.get())
        print("surname:", self.entrySurname.get())
        self.destroy()
 
 
root = tkinter.Tk()
 
showDialogButton = tkinter.Button(root, text="Show dialog",
                                  command=lambda: Dialog(root))
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
showDialogButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

13. Další standardní dialogová okna: otevření dokumentu a uložení dokumentu pod novým jménem

V podpůrných modulech knihovny Tkinter najdeme ještě další tři funkce, po jejichž zavolání se zobrazí standardní dialogová okna. Jedná se o dialog určený pro výběr souboru/dokumentu, který se má otevřít, dále o velmi podobný dialog určený pro uložení dokumentu pod jiným jménem a konečně o dialog určený pro výběr barvy z barvové palety:

Modul Funkce Stručný popis
tkinter.filedialog Open() dialog pro otevření dokumentu/souboru
tkinter.filedialog SaveAs() dialog pro uložení dokumentu pod jiným jménem
tkinter.colorchooser askcolor() dialog pro výběr barvy z palety

14. Šestý příklad – použití dialogového okna pro otevření dokumentu

Otevření či načtení souboru patří mezi často používané operace, proto má mnoho systémů s grafickým uživatelským rozhraním zabudovaný dialog pro výběr jména souboru. Pomocí knihovny Tkinter je možné k tomuto dialogu přistupovat. Potřebná funkce se jmenuje Open a nalezneme ji v modulu tkinter.filedialog. Její použití může vypadat následovně:

def openFileDialog():
    filetypes = [('Python sources', '*.py'),
                 ('Lua sources', '*.lua'),
                 ('All files', '*')]
    dialog = filedialog.Open(root, filetypes=filetypes)
    print(dialog.show())

V nepovinném parametru filetypes je možné specifikovat typy souborů, které mohou být vybrány. Kromě toho lze přes parametry initialdir a initialfile specifikovat adresář, popř. i jméno implicitně vybraného souboru. Pokud dojde k výběru souboru, vrátí se plná cesta k němu, v opačném případě (stisk tlačítka Cancel) se vrátí prázdný řetězec. V případě, že je pomocí volby multiple povolen výběr více souborů, jsou v návratové hodnotě obsaženy všechny vybrané soubory.

Obrázek 10: Dialogové okno pro výběr dokumentu/souboru pro otevření.

Podívejme se nyní, jak lze tuto funkci použít prakticky:

#!/usr/bin/env python
 
import tkinter
from tkinter import filedialog
import sys
 
 
def exit():
    sys.exit(0)
 
 
def openFileDialog():
    filetypes = [('Python sources', '*.py'),
                 ('Lua sources', '*.lua'),
                 ('All files', '*')]
    dialog = filedialog.Open(root, filetypes=filetypes)
    print(dialog.show())
 
 
root = tkinter.Tk()
 
openFileButton = tkinter.Button(root,
                                text="Open file dialog",
                                command=openFileDialog)
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
openFileButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

15. Sedmý příklad – dialog pro uložení dokumentu pod novým jménem

Dialogové okno určené pro uložení dokumentu se v mnohém podobá dialogovému oknu pro jeho otevření. Jediný rozdíl spočívá v odlišném popisu příkazových tlačítek v dialogovém oknu, odlišném titulku (pokud není titulek zadán programově) a také v tom, že soubor, který je určen pro zápis, nemusí existovat – při otevírání souboru probíhají kontroly na jeho existenci.

Obrázek 11: Dialogové okno pro výběr dokumentu/souboru pro uložení.

V dalším demonstračním příkladu je ukázáno, jakým způsobem je možné vytvořit dialogové okno, které uživateli umožní výběr souboru pro zápis:

#!/usr/bin/env python
 
import tkinter
from tkinter import filedialog
import sys
 
 
def exit():
    sys.exit(0)
 
 
def saveFileDialog():
    filetypes = [('Python sources', '*.py'),
                 ('Lua sources', '*.lua'),
                 ('All files', '*')]
    dialog = filedialog.SaveAs(root, filetypes=filetypes)
    print(dialog.show())
 
 
root = tkinter.Tk()
 
saveFileButton = tkinter.Button(root,
                                text="Save as file dialog",
                                command=saveFileDialog)
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
saveFileButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

16. Osmý příklad – výběr barvy z palety

Také pro výběr barvy je možné použít standardní systémové okno. Způsob zobrazení tohoto okna je, podobně jako při otevírání i ukládání souborů, závislý na použitém operačním systému a jeho grafickém uživatelském rozhraní (popravdě řečeno je linuxová varianta dosti nepřehledná). Pokud je barva vybrána, je její hodnota vrácena jako dvojice, přičemž první prvek dvojice obsahuje hodnoty R,G,B (jedná se tedy o trojici) a druhý prvek obsahuje barvu zakódovanou v hexa tripletu #rrggbb, což je způsob kódování barvy, který můžete znát například z HTML. Při zavolání dialogu můžete specifikovat implicitně vybranou barvu:

rgb_values, hexa_triplet = colorchooser.askcolor(color="lightgreen",
                                                 title="Please select any color")
print(rgb_values)
print(hexa_triplet)

Obrázek 12: Výběr barvy.

Následuje výpis zdrojového kódu dnešního posledního demonstračního příkladu:

#!/usr/bin/env python
 
import tkinter
from tkinter import colorchooser
import sys
 
 
def exit():
    sys.exit(0)
 
 
def chooseColorDialog():
    rgb_values, hexa_triplet = colorchooser.askcolor(color="lightgreen",
                                                     title="Please select any color")
    print(rgb_values)
    print(hexa_triplet)
 
 
root = tkinter.Tk()
 
chooseColorButton = tkinter.Button(root,
                                   text="Choose color",
                                   command=chooseColorDialog)
 
quitButton = tkinter.Button(root, text="Exit", command=exit)
 
chooseColorButton.pack(fill=tkinter.BOTH)
 
tkinter.Label(text="").pack()
 
quitButton.pack(fill=tkinter.BOTH)
 
root.mainloop()

17. Repositář s demonstračními příklady

Zdrojové kódy všech osmi dnes popsaných demonstračních příkladů naleznete pod následujícími odkazy:

18. Odkazy na Internetu

  1. Hra Breakout napísaná v Tkinteri
    https://www.root.cz/clanky/hra-breakout-napisana-v-tkinteri/
  2. Hra Snake naprogramovaná v Pythone s pomocou Tkinter
    https://www.root.cz/clanky/hra-snake-naprogramovana-v-pythone-s-pomocou-tkinter/
  3. Python Tkinter Fonts
    https://www.tutorialspoin­t.com/python/tk_fonts.htm
  4. The Tkinter Canvas Widget
    http://effbot.org/tkinter­book/canvas.htm
  5. Ovládací prvek (Wikipedia)
    https://cs.wikipedia.org/wi­ki/Ovl%C3%A1dac%C3%AD_prvek_­%28po%C4%8D%C3%ADta%C4%8D%29
  6. Rezervovaná klíčová slova v Pythonu
    https://docs.python.org/3/re­ference/lexical_analysis.html#ke­ywords
  7. TkDocs: Styles and Themes
    http://www.tkdocs.com/tuto­rial/styles.html
  8. Drawing in Tkinter
    http://zetcode.com/gui/tkin­ter/drawing/
  9. Changing ttk widget text color (StackOverflow)
    https://stackoverflow.com/qu­estions/16240477/changing-ttk-widget-text-color
  10. The Hitchhiker's Guide to Pyhton: GUI Applications
    http://docs.python-guide.org/en/latest/scenarios/gui/
  11. 7 Top Python GUI Frameworks for 2017
    http://insights.dice.com/2014/11/26/5-top-python-guis-for-2015/
  12. GUI Programming in Python
    https://wiki.python.org/mo­in/GuiProgramming
  13. Cameron Laird's personal notes on Python GUIs
    http://phaseit.net/claird/com­p.lang.python/python_GUI.html
  14. Python GUI development
    http://pythoncentral.io/introduction-python-gui-development/
  15. Graphic User Interface FAQ
    https://docs.python.org/2/faq/gu­i.html#graphic-user-interface-faq
  16. TkInter
    https://wiki.python.org/moin/TkInter
  17. Tkinter 8.5 reference: a GUI for Python
    http://infohost.nmt.edu/tcc/hel­p/pubs/tkinter/web/index.html
  18. TkInter (Wikipedia)
    https://en.wikipedia.org/wiki/Tkinter
  19. appJar
    http://appjar.info/
  20. appJar (Wikipedia)
    https://en.wikipedia.org/wiki/AppJar
  21. appJar na Pythonhosted
    http://pythonhosted.org/appJar/
  22. Stránky projektu PyGTK
    http://www.pygtk.org/
  23. PyGTK (Wikipedia)
    https://cs.wikipedia.org/wiki/PyGTK
  24. Stránky projektu PyGObject
    https://wiki.gnome.org/Pro­jects/PyGObject
  25. Stránky projektu Kivy
    https://kivy.org/#home
  26. Stránky projektu PyQt
    https://riverbankcomputin­g.com/software/pyqt/intro
  27. PyQt (Wikipedia)
    https://cs.wikipedia.org/wiki/PyGTK
  28. Stránky projektu PySide
    https://wiki.qt.io/PySide
  29. PySide (Wikipedia)
    https://en.wikipedia.org/wiki/PySide
  30. Stránky projektu Kivy
    https://kivy.org/#home
  31. Kivy (framework, Wikipedia)
    https://en.wikipedia.org/wi­ki/Kivy_(framework)
  32. QML Applications
    http://doc.qt.io/qt-5/qmlapplications.html
  33. KDE
    https://www.kde.org/
  34. Qt
    https://www.qt.io/
  35. GNOME
    https://en.wikipedia.org/wiki/GNOME
  36. Category:Software that uses PyGTK
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_PyGTK
  37. Category:Software that uses PyGObject
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_PyGObject
  38. Category:Software that uses wxWidgets
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_wxWidgets
  39. GIO
    https://developer.gnome.or­g/gio/stable/
  40. GStreamer
    https://gstreamer.freedesktop.org/
  41. GStreamer (Wikipedia)
    https://en.wikipedia.org/wi­ki/GStreamer
  42. Wax Gui Toolkit
    https://wiki.python.org/moin/Wax
  43. Python Imaging Library (PIL)
    http://infohost.nmt.edu/tcc/hel­p/pubs/pil/
  44. Why Pyjamas Isn’t a Good Framework for Web Apps (blogpost z roku 2012)
    http://blog.pyjeon.com/2012/07/29/why-pyjamas-isnt-a-good-framework-for-web-apps/
Našli jste v článku chybu?