V úvodu druhého dílu o wxPython bych rád zdůraznil, že se jedná o plně objektové GUI prostředí a podle toho se odvíjí i celková filozofie tvorby všech aplikací používajících wxPython. Základem každé aplikace je třída, která je potomkem mateřské třídy wxApp a dědí její metodu OnInit() . A právě tato metoda nám vytváří základní okno jako výchozí framework pro všechny své další potomky typu MDI Frame, vestavěná dialogová okna typu wxFileDialog… nebo uživatelská dialogová okna typu wxDialog atd.
01. #!/usr/local/bin/env python 02. 03. from wxPython import * 04. 05. class MyApp(wxApp): 06. 07. def OnInit(self): 08. frame = wxFrame(NULL, -1, "Základní projekt") 09. frame.Show(true) 10. self.SetTopWindow(frame) 11. return(true) 12. 13. app = MyApp(0) 14. app.MainLoop()
Na řádku 03. dochází k importu všech dostupných modulů z knihovny wxPython. Lze samozřejmě provést import pouze jednotlivých modulů, ale doporučuji tento plný import, abychom si nemuseli hlídat případné závislosti.
Pomocí děděné metoty třídy wxApp provedeme na řádku 09. zobrazení vlastního okna a metodou self.SetTopWindow() informujeme knihovnu o tom, že je toto okno hlavní oknem aplikace. Při ukončení tohoto okna dojde i k ukončení vlastní aplikace.
Na řádku 13. vytvoříme instanci třídy MyApp a zavoláme její metodu app.MainLoop(), která zajistí průběh nekonečné smyčky až do doby zavření hlavního okna aplikace.
Toto obecné schéma skriptu budeme používat prakticky ve všech aplikacích používajících jako GUI rozhraní právě knihovnu wxPython.
Přidání námi definované třídy hlavního okna:
01. #!/usr/local/bin/env python 02. 03. from wxPython import * 04. 05. Title = "Projekt" 06. 07. class MyFrame(wxFrame): 08. 09. def __init__(self, parent, id, title): 10. 11. wxFrame.__init__(self, parent, id,wxPoint(150,150), 12. wxSize(650, 400)) 13. 14. self.CenterOnScreen() 15. 16. class MyApp(wxApp): 17. 18. def OnInit(self): 19. frame = MyFrame(NULL, -1, Title) 20. frame.Show(true) 21. self.SetTopWindow(frame) 22. return(true) 23. 24. app = MyApp(0) 25. app.MainLoop()
Oproti předchozímu kódu se nám již aplikace rozrostla o námi definovanou třídu MyFrame, která dědí všechny vlastnosti třídy wxFrame.
Třída wxFrame:
Pro úplnost si uvedeme i předky této třídy, z kterých dědí důležité metody:
wxWindow, wxEvtHandler, wxObject
Defaultní konstruktor této třídy má následující formát :
wxFrame.__init__( parent, id, title, pos, size, style, name )
Parametry třídy wxFrame :
První čtyři parametry jsou povinné, zbývající volitelné,
- parent má defaultně hodnotu NULL, v dalších případech budeme psát obecně self jako ukazatel na okno, v němž bude tento objekt obsažen.
- id vyjadřuje identifikátor našeho okna, podle kterého se na něj můžeme odkazovat. Defaultně má hodnotu –1 , v ostatních případech hodnotu typu integer .
- pos určuje pozici okna na obrazovce pomocí třídy wxPoint(int, int). Defaultně má hodnotu (-1, –1) , v ostatních případech dle požadované pozice.
- size určuje velikost okna pomocí třídy wxSize(int, int). Defaultně má hodnotu (-1, –1 ) , v ostatních případech dle požadované velikosti.
- style nabývá následujících hodnot :
- wxMAXIMIZE
- wxMINIMIZE
- wxICONIZE
- wxSYSTEM_MENU
- wxSIMPLE_BORDER
- wxRESIZE_BORDER
- wxSTAY_ON_TOP
- wxDEFAULT_FRAME_STYLE , který v sobě zahrnuje defaultně styly wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BOX | wxSYSTEM_MENU | wxCAPTION
- name určuje jméno okna a má význam pouze při používání knihovny Motif, osobně jsem tento parametr nikdy nepoužil.
Metody třídy wxFrame
Vyjmenuji zde pouze ty metody, které mají praktický význam pro náš seriál, jinak jich tato třída obsahuje mnohem více, ale nechci zde vytvářet doslovný překlad referenční příručky pro knihovnu wxWindow.
- wxFrame.CreateStatusBar() nám vytvoří status bar při dolním okraji okna.
- wxFrame.CreateToolBar() obdobně vytvoří toolbar při horním okraji okna.
- wxFrame.SetMenuBar() definuje zobrazení menu asociovaného k volajícímu oknu.
- wxFrame.SetStatusWidths() definuje počet polí a jejich velikost ve status baru. Indexace polí je od 0…n u prvního pole a obráceně 0…-1 u posledního pole, jak jsme v pythonu obecně zvyklí.
- wxFrame.SetStatusText() definuje text, který se nám po zobrazení okna objeví ve status baru. Zde platí stejná zásada pro indexaci polí.
- wxFrame.SetTitle() nám umožňuje dle potřeby i za běhu aplikace měnit název hlavního okna.
Rozšíření projektu
A nyní v našem projektu použijeme výše popsané nové metody třídy wxFrame. Zkusíme hned něco praktického a přidáme si do status baru zobrazení aktuálního datumu a času. Přeci jenom, když se něco v okně hýbe, je to už zábavnější.
01. #!/usr/local/bin/env python 02. 03. from wxPython import * 04. import time 05. 06. Title = "Projekt" 07. 08. class MyFrame(wxFrame): 09. 10. def __init__(self, parent, id, title): 11. 12. wxFrame.__init__(self, parent, id,wxPoint(150,150), 13. wxSize(650, 400)) 14. 15. self.CenterOnScreen() 16. 17. sb = self.CreateStatusBar(2) 18. sb.SetStatusWidths([-1, 130]) 19. 20. self.timer = wxPyTimer(self.Notify) 21. self.timer.Start(1000) 22. self.Notify() 23. 24. def Notify(self): 25. 26. t = time.localtime(time.time()) 27. st= time.strftime("%d-%b-%Y %I:%M:%S", t) 28. self.SetStatusText(st, 1) 29. 30. class MyApp(wxApp): 31. 32. def OnInit(self): 33. frame = MyFrame(NULL, -1, Title) 34. frame.Show(true) 35. self.SetTopWindow(frame) 36. return(true) 37. 38. app = MyApp(0) 39. app.MainLoop()
Na řádku 17. vytvoříme status bar o dvou polích a na řádku18. určíme šířku druhého pole, do kterého na řádku 28. umístíme námi požadované zobrazení aktuálního datumu a času.
A co nás čeká v příštím pokračování? Naučíme se vytvářet nabídky typu wxMenu a ukážeme si, jak naše aplikace rozpozná, pod kterým operačním systémem je spuštěna. Přidáme si i systémovou ikonu naší aplikace.