4 | ||
Editor: geon
Time: 2011/10/12 18:27:43 GMT+2 |
||
Note: oprava |
changed: - ..aneb co se v dokumentaci těžko hledá... .. image:: py25.png :align: right Bez černého konzolového okna ------------------------------------ Pokud nechceme, aby se otevíralo černé dosovské okno, stačí dát příponu programu ``*.pyw`` nebo ke spouštění použít místo python.exe pythonw.exe. Nevýhoda tohoto způsobu při vytváření aplikace je jasná: neuvidíte případné chybové hlášky a nebudete moci ani používat print. Řešením tohoto problému nicméně může být přesměrování stdout a stderr do okna. Následující příklad to dělá. Okno pro výpisy je po spuštění zavřené a otevře se až v případě zápisu do stdout či stderr. Výpisy na stderr zobrazuje červeně. Okno je možné zavřít, v případě potřeby se zase otevře. Příklad :: import sys from Tkinter import * hlavni=Tk() _printtext = None def getprinttext(): global _printtext if _printtext == None: printwin = Toplevel() def reset(): global _printtext _printtext = None printwin.destroy() printwin.protocol("WM_DELETE_WINDOW", reset) _printtext = Text(printwin) _printtext.pack(expand=True, fill=BOTH) _printtext.tag_config('out', foreground="black") _printtext.tag_config('err', foreground="red") return _printtext class FakeStdOut(object): def write(self, what): getprinttext().insert(END, what, 'out') class FakeStdErr(object): def write(self, what): getprinttext().insert(END, what, 'err') oldso = sys.stdout oldse = sys.stderr sys.stdout = FakeStdOut() sys.stderr = FakeStdErr() def so(): print 'aaaaaa' def se(): print >> sys.stderr, 'bbbbbbb' try: Button(text="stdout", command=so).pack() Button(text="stderr", command=se).pack() Button(text="Sbohem", command='exit').pack() hlavni.mainloop() except SystemExit: pass except: sys.stdout = oldso sys.stderr = oldse import traceback traceback.print_exc() Schování widgetu --------------------- Ukrytí widgetu se dá udělat pomocí metody widget.pack_forget() a následné zobrazení pomocí widget.pack(). U grid manageru je to widget.grid_remove() a zobrazení pak s widget.grid() a mělo by to být na tom samém místě. Ukázka:: # -*- coding: utf8 -*- """Ukazkovy priklad v Tkinter.""" from Tkinter import * priznak=True def tisk(): global priznak print priznak if priznak: listbox.pack_forget() tisk['text']='Zobrazit!' else: listbox.pack() tisk['text']='Schovat!' priznak = not priznak hlavniOkno=Tk() hlavniOkno.title('Aplikace v Tk') ramec=Frame(hlavniOkno) ramec.pack() listbox=Listbox(ramec, selectmode=MULTIPLE) seznam=['Python','C++', 'Java', 'Pascal', 'Basic'] for prvek in seznam: listbox.insert(END, prvek) listbox.pack() tisk=Button(hlavniOkno, text='Schovat!', command=tisk) tisk.pack(ipadx=40) mainloop() Změna systémové ikony ----------------------- Tak na tohle má Tkinter metodu iconbitmap. Použití je např. následující: ``root.iconbitmap("cherry.ico")``, cherry.ico je soubor s ikonou ve formatu ``*.ico`` Okno pořád na vrchu, okno nejde zavřít --------------------------------------------- Chcete aby bylo okno pořád vidět, aby se nedalo schovat za ostatní? a ještě aby nešlo standardním způsobem (křížek nebo Alt+F4) zavřít? Použijte následující kod:: root=Tk() # okno root.protocol('WM_DELETE_WINDOW', 0 ) # aby nešlo zavřít, místo 0 možno použít nějakou funkci na případnou hlášku root.protocol('WM_TAKE_FOCUS', root.update ) # aby se stalo aktivním root.wait_visibility(root) # aby fungoval následující řádek root.attributes('-topmost',1) # aby bylo pořád navrchu Okno bez rámu, bez ikony, bez title a bez ovládacích prvků ------------------------------------------------------------ :: from Tkinter import * root = Tk() Label(root, text='No wm decorations').pack(padx=10, pady=10) root.overrideredirect(1) root.mainloop() Pokud ještě potřebujete zobrazit aplikaci přes celou obrazovku a neznáte předem rozlišení, je možné přidat v předchozím kódu před mainloop():: w, h = root.winfo_screenwidth(), root.winfo_screenheight() root.geometry("%dx%d%+d%+d" % (w,h,0,0)) Hromadná změna vzhledu u všech widgetů --------------------------------------- "Ošklivý" vzhled standardního vzhledu Tk oken můžete změnit pomocí databáze voleb (option database). Dá se to provést buď přímo v programu:: # -*- coding: utf8 -*- from Tkinter import * hlavni=Tk() hlavni.option_add('*background','#797778') hlavni.option_add('*Font', 'Verdana 20 bold') # dalsi moznosti # hlavni.option_add('*background','#797778') # hlavni.option_add('*foreground','#fdfd02') # hlavni.option_add('*EntryField.Entry.background', 'white') # hlavni.option_add('*Entry.background', 'white') # hlavni.option_add('*MessageBar.Entry.background', 'gray85') # hlavni.option_add('*Listbox*background', 'dark green') # hlavni.option_add('*Listbox*selectBackground', 'dark slate blue') # hlavni.option_add('*Listbox*selectForeground', 'white') w=Label( text="Ahoj světe!") w.pack() mainloop() nebo načtením z externího souboru s nastaveními:: *font : Helvetica -12 *Entry*background : white *Listbox*background : white *Listbox*exportSelection : 0 *selectBackground : blue4 *selectForeground : white *Scrollbar*takeFocus : 0 *Scrollbar*highlightThickness : 0 *Menu*tearOff : 0 atd. Když uložíte toto jako "optionDB", tak pak následně v programu můžete nastavení načíst takto:: root = Tk() root.option_readfile(<cesta-k-optionDB>) Tk podporuje i barevná schémata. Následující kód nastaví modrý vzhled, ostatní barvy se vypočítají tak, aby byl zajištěn barevný kontrast všech prvků uživatelského rozhraní:: root = Tk() root.tk_setPalette('blue') Scrollování kolečkem myši ------------------------------ Scrolování textu pomocí kolečka myši umožňuje nedokumentovaná událost na Linuxech 'Button-4' a 'Button-5' a na Windows <!MouseWheel>, kde existuje atribut 'delta', který udává směr.:: import Tkinter def priRolovani(udalost): print "udalost:", udalost," --- smer:", udalost.delta okno=Tkinter.Tk() okno.bind('<MouseWheel>', priRolovani) text=Tkinter.Label(okno, text="SCROLUJ a ROLUJ!", font="Arial 20") text.pack(padx=40, pady=40) okno.mainloop() Poloha kurzoru v textu ----------------------------- :: text.get(INSERT) # zjisteni text.mark_set(INSERT, "2.7") # nastaveni Místní nabídka aneb menu na pravém tlačítku ------------------------------------------- :: from Tkinter import * root = Tk() def hello(): print "hello!" def popup(event): menu.post(event.x_root, event.y_root) menu = Menu(root, tearoff=0) menu.add_command(label="Undo", command=hello) menu.add_command(label="Redo", command=hello) frame = Frame(root, width=512, height=512) frame.pack() frame.bind("<Button-3>", popup) mainloop() Ovládání kurzoru myši ----------------------- :: widget.event_generate("<Motion>", warp=1, x=..., y=...) Aby podokno bylo aktivní --------------------------- :: podokno.focus_set() # aby bylo okno aktivní podokno.transient(hlavni) # je považováno za dialogové okno - s minimalizací hlavního okna # se minimalizuje také, není vidět na hlavní liště podokno.grab_set() # aby nešlo zpátky přepnout do hlavního okna, dokud se neukončí podokno Vycentrování okna na střed obrazovky ----------------------------------------- :: from Tkinter import * root = Tk() w=root.winfo_screenwidth() h=root.winfo_screenheight() sirka=400 vyska=200 root.geometry("%dx%d+%d+%d" % ( sirka, vyska, (w-sirka)/2, (h-vyska)/2 ) ) root.mainloop() Přesměrování výstupu do okna --------------------------------- :: # -*- coding: utf-8 -*- from Tkinter import * from ScrolledText import ScrolledText import sys class py_message_box: def __init__(self, parent): self.frame = Frame(parent) self.frame.pack() self.text = ScrolledText(self.frame, background='black', foreground='green', font=("Courier", 9)) self.text.pack() def write(self, s): self.text.insert(END, s) self.text.see(END) root=Tk() text_window = py_message_box(root) sys.stdout = text_window sys.stderr = text_window for i in range(44): print i, "Toto je pokus o presmerovanie printu do okna" # toto se vytiskne do GUI okna print tojealechyba # a toto taky root.mainloop() Maximalizace okna (win) -------------------------- :: from Tkinter import * okno=Tk() okno.wm_state('zoomed') mainloop()
..aneb co se v dokumentaci těžko hledá...
Pokud nechceme, aby se otevíralo černé dosovské okno, stačí dát příponu programu *.pyw nebo ke spouštění použít místo python.exe pythonw.exe. Nevýhoda tohoto způsobu při vytváření aplikace je jasná: neuvidíte případné chybové hlášky a nebudete moci ani používat print.
Řešením tohoto problému nicméně může být přesměrování stdout a stderr do okna. Následující příklad to dělá. Okno pro výpisy je po spuštění zavřené a otevře se až v případě zápisu do stdout či stderr. Výpisy na stderr zobrazuje červeně. Okno je možné zavřít, v případě potřeby se zase otevře. Příklad
import sys from Tkinter import * hlavni=Tk() _printtext = None def getprinttext(): global _printtext if _printtext == None: printwin = Toplevel() def reset(): global _printtext _printtext = None printwin.destroy() printwin.protocol("WM_DELETE_WINDOW", reset) _printtext = Text(printwin) _printtext.pack(expand=True, fill=BOTH) _printtext.tag_config('out', foreground="black") _printtext.tag_config('err', foreground="red") return _printtext class FakeStdOut(object): def write(self, what): getprinttext().insert(END, what, 'out') class FakeStdErr(object): def write(self, what): getprinttext().insert(END, what, 'err') oldso = sys.stdout oldse = sys.stderr sys.stdout = FakeStdOut() sys.stderr = FakeStdErr() def so(): print 'aaaaaa' def se(): print >> sys.stderr, 'bbbbbbb' try: Button(text="stdout", command=so).pack() Button(text="stderr", command=se).pack() Button(text="Sbohem", command='exit').pack() hlavni.mainloop() except SystemExit: pass except: sys.stdout = oldso sys.stderr = oldse import traceback traceback.print_exc()
Ukrytí widgetu se dá udělat pomocí metody widget.pack_forget() a následné zobrazení pomocí widget.pack(). U grid manageru je to widget.grid_remove() a zobrazení pak s widget.grid() a mělo by to být na tom samém místě.
Ukázka:
# -*- coding: utf8 -*- """Ukazkovy priklad v Tkinter.""" from Tkinter import * priznak=True def tisk(): global priznak print priznak if priznak: listbox.pack_forget() tisk['text']='Zobrazit!' else: listbox.pack() tisk['text']='Schovat!' priznak = not priznak hlavniOkno=Tk() hlavniOkno.title('Aplikace v Tk') ramec=Frame(hlavniOkno) ramec.pack() listbox=Listbox(ramec, selectmode=MULTIPLE) seznam=['Python','C++', 'Java', 'Pascal', 'Basic'] for prvek in seznam: listbox.insert(END, prvek) listbox.pack() tisk=Button(hlavniOkno, text='Schovat!', command=tisk) tisk.pack(ipadx=40) mainloop()
Tak na tohle má Tkinter metodu iconbitmap. Použití je např. následující: root.iconbitmap("cherry.ico"), cherry.ico je soubor s ikonou ve formatu *.ico
Chcete aby bylo okno pořád vidět, aby se nedalo schovat za ostatní? a ještě aby nešlo standardním způsobem (křížek nebo Alt+F4) zavřít? Použijte následující kod:
root=Tk() # okno root.protocol('WM_DELETE_WINDOW', 0 ) # aby nešlo zavřít, místo 0 možno použít nějakou funkci na případnou hlášku root.protocol('WM_TAKE_FOCUS', root.update ) # aby se stalo aktivním root.wait_visibility(root) # aby fungoval následující řádek root.attributes('-topmost',1) # aby bylo pořád navrchu
from Tkinter import * root = Tk() Label(root, text='No wm decorations').pack(padx=10, pady=10) root.overrideredirect(1) root.mainloop()
Pokud ještě potřebujete zobrazit aplikaci přes celou obrazovku a neznáte předem rozlišení, je možné přidat v předchozím kódu před mainloop():
w, h = root.winfo_screenwidth(), root.winfo_screenheight() root.geometry("%dx%d%+d%+d" % (w,h,0,0))
"Ošklivý" vzhled standardního vzhledu Tk oken můžete změnit pomocí databáze voleb (option database). Dá se to provést buď přímo v programu:
# -*- coding: utf8 -*- from Tkinter import * hlavni=Tk() hlavni.option_add('*background','#797778') hlavni.option_add('*Font', 'Verdana 20 bold') # dalsi moznosti # hlavni.option_add('*background','#797778') # hlavni.option_add('*foreground','#fdfd02') # hlavni.option_add('*EntryField.Entry.background', 'white') # hlavni.option_add('*Entry.background', 'white') # hlavni.option_add('*MessageBar.Entry.background', 'gray85') # hlavni.option_add('*Listbox*background', 'dark green') # hlavni.option_add('*Listbox*selectBackground', 'dark slate blue') # hlavni.option_add('*Listbox*selectForeground', 'white') w=Label( text="Ahoj světe!") w.pack() mainloop()
nebo načtením z externího souboru s nastaveními:
*font : Helvetica -12 *Entry*background : white *Listbox*background : white *Listbox*exportSelection : 0 *selectBackground : blue4 *selectForeground : white *Scrollbar*takeFocus : 0 *Scrollbar*highlightThickness : 0 *Menu*tearOff : 0 atd.
Když uložíte toto jako "optionDB", tak pak následně v programu můžete nastavení načíst takto:
root = Tk() root.option_readfile(<cesta-k-optionDB>)
Tk podporuje i barevná schémata. Následující kód nastaví modrý vzhled, ostatní barvy se vypočítají tak, aby byl zajištěn barevný kontrast všech prvků uživatelského rozhraní:
root = Tk() root.tk_setPalette('blue')
Scrolování textu pomocí kolečka myši umožňuje nedokumentovaná událost na Linuxech 'Button-4' a 'Button-5' a na Windows <MouseWheel>, kde existuje atribut 'delta', který udává směr.:
import Tkinter def priRolovani(udalost): print "udalost:", udalost," --- smer:", udalost.delta okno=Tkinter.Tk() okno.bind('<MouseWheel>', priRolovani) text=Tkinter.Label(okno, text="SCROLUJ a ROLUJ!", font="Arial 20") text.pack(padx=40, pady=40) okno.mainloop()
text.get(INSERT) # zjisteni text.mark_set(INSERT, "2.7") # nastaveni
widget.event_generate("<Motion>", warp=1, x=..., y=...)
podokno.focus_set() # aby bylo okno aktivní podokno.transient(hlavni) # je považováno za dialogové okno - s minimalizací hlavního okna # se minimalizuje také, není vidět na hlavní liště podokno.grab_set() # aby nešlo zpátky přepnout do hlavního okna, dokud se neukončí podokno
from Tkinter import * root = Tk() w=root.winfo_screenwidth() h=root.winfo_screenheight() sirka=400 vyska=200 root.geometry("%dx%d+%d+%d" % ( sirka, vyska, (w-sirka)/2, (h-vyska)/2 ) ) root.mainloop()
# -*- coding: utf-8 -*- from Tkinter import * from ScrolledText import ScrolledText import sys class py_message_box: def __init__(self, parent): self.frame = Frame(parent) self.frame.pack() self.text = ScrolledText(self.frame, background='black', foreground='green', font=("Courier", 9)) self.text.pack() def write(self, s): self.text.insert(END, s) self.text.see(END) root=Tk() text_window = py_message_box(root) sys.stdout = text_window sys.stderr = text_window for i in range(44): print i, "Toto je pokus o presmerovanie printu do okna" # toto se vytiskne do GUI okna print tojealechyba # a toto taky root.mainloop()
from Tkinter import * okno=Tk() okno.wm_state('zoomed') mainloop()