Prostředí Cinnamon a Mate jsou založená na knihovně GTK (Gimp the toolkit), která vznikla jako grafický framework pro populární editor obrázků, aby tak nahradil jeho původní, nesvobodnou verzi. Na tomto rozhraní postavila později GNU prostředí Gnome, od kterého se prostředí MATE a Cinnamon později oddělily. Ale stále tyto knihovny používá a je tak možno toto rozhraní používat. Knihovna PyGTK právě umožňuje spolupráci s GTK.
Pomůcky
Při programování si vystačíme s výchozím gedit, nebo vhodněji s IDE Geany, které já osobně používám (ale možná přejdu na komerční Sublime text). Dále se také vyplatí instalovat vývojářskou nápovědu „devhelp“.
Příkaz terminálu: |
---|
sudo apt-get install devhelp geany |
Práce s devhelp je jednoduchá, jedná se o manuál (anglicky), kde zvolíte jazyk (knihu), ve kterém chcete hledat. (Zde využijete hlavně PyGTK 2.0 manuál)
Základní okno s pevnou pozicí a rozměry
V tomto příkladě si vytvoříme obyčejné okno, na kterém si popíšeme základy práce s gtk. Zdrojový kód bude na konci této části ke stáhnutí, to bude platit i o dalších příkladech:
#/usr/bin/env python
# -*- Mode: Python; coding: utf-8;
import gtk
První řádek je deklarace prostředí, resp. kompilátoru, druhý řádek obsahuje již informace pro kompilaci, zde se jedná o informace, že se jedná o Python a že, což je důležité pro nás, co rádi používáme diakritiku, se použije kódování UTF 8, bez kterého by neprobíhala kompilace v pořádku a hlásila by chyby při objevení nestandardních ASCII znaků. Typicky znaky s diakritikou. Na třetím řádku je již samotný kód v Pythonu, ovšem velmi podstatný, dochází zde k importování třídy gtk, která právě vytváří, resp. obsahuje všechny grafické prvky, které můžete použít.
class PyApp(gtk.Window):
def __init__(self):
super(PyApp, self).__init__()
Vytvoříme novou třídu PyApp (4), která rozšiřuje gtk.Window a založíme funkci, která bude spouštěna při inicializaci (5. řádek, běžný postup u definovaných tříd). Řádkem 6. voláme konstruktor, berme to jako jakési magické zaklínadlo, které nemá pro nás význam, ale bez něj to nejde (Poznámka: 6. řádek má obsahovat stejně podtržítka jako v řádku 5., ale místní nastavení WP mi to tu nějak kazí).
| self.connect(„destroy“, gtk.main_quit)
self.set_size_request(250, 150)
self.set_position(gtk.WIN_POS_CENTER)
self.show()
Na prvním řádku spojujeme signál s gtk.main_quit (viz níže u gtk.main()). Signály jsou události provedené v grafickém prostředí a my je využíváme při volání námi nadefinovaných funkcí. Zde je to signál destroy, tedy při zničení okna (Alt + F4, či klepnutím na zavřít). Řádek 8. předává manažeru oken žádost o „přidělení“ velikosti okna v pořadí délka (po ose x) výška (po ose y). Manažeru oken předává informaci i 9. řádek, kde při volání nastavení pozice použijeme systémovou konstantu WIN_POS_CENTER, která žádá o střed obrazovky, pro více možností si prohlédněte devhelp. Poslední řádek zobrazuje celý výtvor (self.show() se zaměňuje za self.show_all(), které zobrazí i potomky třídy.) (Poznámka: WP mi kazí odsazení, proto je v prvním řádku na začátek přidáno svislítko – |.)
Deklarace třídy je dokončena, teď již ji pouze bude volat
PyApp()
gtk.main()
První řádek zavolá třídu, ta se zinicializuje viz 3. řádek a poté zavoláme smyčku – gtk.main(), ta se přeruší pouze při gtk.main_quit() viz spojení destroyed právě s gtk.main_quit.
Zkuste si příklad spustit (v IDE Geany pouze při klepnutí na F5). Jinak musíte přidělit spouštěcí práva souboru *.py (obsahujícím kód) a pustit ho (přes terminál „python soubor.py“, kde můžete také provádět jakýsi debugging). Zdrojový kód naleznete zde.
Jednoduché ovládání Banshee
Uděláme si takový jednoduchý ovladač Banshee, který můžete nasadit přes další okna… Je to sice nepraktické, ale poučné.
Návrh GUI
Pokud chci něco smysluplného udělat je nanejvýš vhodné si před samotným programováním sednout a vymyslet koncept, tedy návrh, čeho chci dosáhnout, při jasně nastavených cílech také lépe pracuje motivace a člověk je tak spokojenější (zcela neobjektivní, spíše subjektivní dojem). Nepotřebujete nějaký software, pro návrh vám stačí hlava, tužka, papír. Vhodné je také vědět, čeho můžu s GTK dosáhnout, nastíním, co máme k dispozici (základní věci). K dispozici máme tabulkové layouty. Tedy vytvoření sloupců a do nich vkládání řádků, či obráceně.
Vpravo vidíte jeden takový návrh (velmi neumělý), ale máme z něj představu, jak bude vypadat návrh okna tabulka 2*3 a v ní budou tlačítka pro ovládání. Takže naše rozhraní bude obsahovat hlavní VBox, v něm dva HBoxy o šířce 3, kde spodní bude obsahovat 3 tlačítka a horní pouze 1 (můžeme, ale snadno rozšířit, například pro otevírání složky k přehrátí, apod.) Co budou tlačítka volat? Banshee se dá ovlivňovat v sezení i z příkazové řádky.
Samotná programová část
Pozor, tento kód berte jako inspirativní, místní nastavení mi kazí odražení (<tab>), stahujte kód viz níže:
#/usr/bin/env python
# -*- Mode: Python; coding: utf-8;
import gtk
import os
class PyApp(gtk.Window):
def __init__(self):
super(PyApp, self).__init__()
string = os.popen(‚ps -e | grep banshee‘).read()
if string == „“:
os.popen(‚banshee &amp;amp;amp;‘)
self.connect(„destroy“, gtk.main_quit)
self.set_size_request(250,150)
self.set_position(gtk.WIN_POS_CENTER)
self.set_title(„Banshee ovladač“)
Zde je základní definice, jako například importované poznámky a základní nastavení velikosti oken, hlavně podstatné je self.connect(„destroy“, gtk.main_quit), které připojuje událost zavření hlavního okna k funkci gtk.main_quit(), která vyskakuje ze smyčky gtk.main a přenechává další běh programů. Mimo jiné si všimněte os.popen(‚banshee‘) s podmínkou, která pracuje jako kontrola, jestli banshee běží, a jestli ne, tak ho zapneme.
#### Základní rozvržení
self.VBox = gtk.VBox(True, 3)
self.HorniBox = gtk.HBox(True, 3)
self.SpodniBox = gtk.HBox(True, 3)
self.VBox.pack_start(self.HorniBox)
self.VBox.pack_start(self.SpodniBox)
self.add(self.VBox)
#### Tlačítka
self.PlayPause = gtk.Button(„PlayPause“)
#self.RefreshStock()
self.PlayPause.connect(„clicked“, self.PlayPauseFunc) #Připojím na akci PlayPause
self.Next = gtk.Button(„Další“)
self.Next.connect(„clicked“, self.NextFunc)
self.Prev = gtk.Button(„Předchozí“)
self.Prev.connect(„clicked“, self.PrevFunc)
self.Stop = gtk.Button(„Zastavit“)
self.Stop.connect(„clicked“, self.StopFunc)
### Rozvržení
##### Horní část
self.HorniBox.pack_start(gtk.Label(„“)) # Prázdná místa …
self.HorniBox.pack_start(self.PlayPause)
self.HorniBox.pack_start(gtk.Label(„“)) # Prázdné místo …
##### Spodní část
self.SpodniBox.pack_end(self.Next)
self.SpodniBox.pack_end(self.Stop)
self.SpodniBox.pack_end(self.Prev)
self.show_all()
self.RefreshStock()
Tato část se stará o vytvoření prvků GUI vytváříme nejprve boxy (VBox a HBox), které jsme do sebe umístili tak, že vytvořili tabulku 2×3 a dále také vytvoříme tlačítka (4) a spojujeme jejich signály s funkcemi (viz .connect(„clicked“, self.funkce) ) V závěrečné části kódu zapojujeme do tabulky i zbylé prvky (gtk.Label(„“) jsou prázdná pole, zde by teoreticky šlo vypisovat název písničky, apod.) show_all() zajišťuje zobrazení všech prvků a funkce self.RefreshStock() je námi nadefinovaná funkce k aktualizaci tlačítek Play/Pause:
def RefreshStock(self):
string = os.popen(‚banshee –query-current-state‘).read().replace(„\n“, „“).split(„:“)[1][1:]
if string == „playing“:
self.PlayPause.set_label(„Pozastavit“)
else:
self.PlayPause.set_label(„Přehrát“)
#Obnoví obrázek Play/Pause
[/python]
Funkce obnovuje nápis Pozastavit / Přehrávat na Tlačítku
[python firstline=“50″]
def PlayPauseFunc(self, widget):
#Spustí / Pozastaví přehrávání na základě stavu
string = os.popen(‚banshee –query-current-state‘).read().replace(„\n“, „“).split(„:“)[1][1:]
if string == „playing“:
os.system(„banshee –pause“)
else:
os.system(„banshee –play“)
self.RefreshStock()
Funkce pro pozastavení / pokračování přehrávání na základě výstupu (banshee –query-current-state) pokud přehrává pauznout a obráceně. Na konci dojde k aktualizace nápisu Pozastavit / Přehrát:
def NextFunc(self, widget):
#Další skladba
os.system(„banshee –next“)
def PrevFunc(self, widget):
#Předchozí skladba
os.system(„banshee –previous“)
def StopFunc(self, widget):
#Zastavit přehrávání
os.system(„banshee –stop“)
self.RefreshStock()
Zbylé funkce pro ovládání tlačítek se od sebe vzájemně neliší, vychází z banshee –help a pouze zastavení přehrávání vyvolá logicky změnu tlačítka přes self.RefreshStock():
#Samotné volání aplikace při spuštění
PyApp()
gtk.main()
Zdrojové kódy aplikace stahujte zde (main.py), protože místní nastavení mi tento kód ničí a tak ho prosím nekopírujte přímo ze stránky.
Rozhodně si to mnohokrát zkoušejte je to snadné a velmi zábavné, až návykové… Jinak GTK se může dostat na vedlejší kolej, tlačí se tu Qt a další… Nicméně si myslím, že ke dobré nějak začít a přispět k vývoji LM se dá právě skrze PyGTK koukněte se na GitHub, které věci jsou tvořené přes PyGTK a pokud se naučíte ještě C, tak to už bude na našem Githubu 99% věcí, na které si budete moci sáhnout a věřte, že není lepší pocit, než se přiblížit tomu, jak systém funguje!