Hlavní navigace

Cirkus s okny: třída wxFrame

Zdeněk Král 17. 12. 2002

V dnešním pokračování o knihovně wxPython si budeme definovat naši vlastní třídu rodičovského okna a seznámíme se tak s třídou wxFrame jako výchozím prvkem pro tvorbu grafického rozhraní. Pomocí metod této třídy rozšíříme náš základní projekt o běžné prvky typu status bar, toolbar, kontextové nabídky a další.

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_FRA­ME_STYLE , který v sobě zahrnuje defaultně styly wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BOX | wxSYSTEM_MENU | wxCAPTION
    Styly lze v zadání parametrů kombinovat pomocí znaku | , pokud neuvedeme v parametru žádný styl, bude použit defaultně wxDEFAULT_FRA­ME_STYLE a naše hlavní okno se bude chovat, jak jsme obecně v GUI zvyklí.
  • 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.CreateS­tatusBar() nám vytvoří status bar při dolním okraji okna.
  • wxFrame.Create­ToolBar() obdobně vytvoří toolbar při horním okraji okna.
  • wxFrame.SetMe­nuBar() definuje zobrazení menu asociovaného k volajícímu oknu.
  • wxFrame.SetSta­tusWidths() 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.SetSta­tusText() 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.

Našli jste v článku chybu?

20. 12. 2002 22:27

Zdeněk Král (neregistrovaný)

Musim podotknout, ze pouzivam prakticky pouze RedHat
a SuSE. Na obou distribucich jsem experimentoval se
zadavanim - #!/usr/bin/env python - ve vsech variantach, vcetne .../env python2, ale prave na
distribucich RedHat do verze 7.1Cz i Us dochazi k
chybam pri spousteni skriptu s wxPython, ktera se
spatne linkuje ke skriptum.A zatim jsem mel vzdy
bezproblemove spusteni prave s ".../local/bin/env"
a vzdy doslo k nalinkovani wxPython. Nejsem na Linux
jako OS zadny guru a zde uvadim pouze s…







19. 12. 2002 21:08

martin (neregistrovaný)

A kdyz uz jsme u toho shromazdovani chyb,
#! /usr/local/bin/env python
asi taky moc lidem fungovat nebude.
Tahle konstrukce s env se pouziva kvuli tomu, ze nekde je python v /usr/bin, jinde v /usr/local/bin,
ale env byva vsude /usr/bin/env
(tento zmatek zacina uz v prvnim dile...)

S tim spoustenim na rh7 bych to spis resil nalinkovanim
ln python python2 (pokud uz neni)
a
#!/usr/bin/env python2


Ale kazdopadne diky za zajimavy serial














Podnikatel.cz: Babiše přesvědčila 89letá podnikatelka?!

Babiše přesvědčila 89letá podnikatelka?!

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Vitalia.cz: Pečete cukroví a zbyl vám bílek?

Pečete cukroví a zbyl vám bílek?

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

Lupa.cz: Babiš: E-shopů se EET možná nebude týkat

Babiš: E-shopů se EET možná nebude týkat

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Na poslední chvíli šokuje výjimkami v EET

Na poslední chvíli šokuje výjimkami v EET

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

120na80.cz: Boreliózu nelze žádným testem prokázat

Boreliózu nelze žádným testem prokázat

DigiZone.cz: ČT má dalšího zástupce v EBU

ČT má dalšího zástupce v EBU

Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

Lupa.cz: Seznam mění vedení. Pavel Zima v čele končí

Seznam mění vedení. Pavel Zima v čele končí

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí