WxPython jest platformą pozwalającą tworzyd aplikacje okienkowe nie tylko dla systemu Windows ale i Mac czy Unix.
Instalujemy:
1. Ze strony: http://www.wxpython.org/download.php#stable wybieramy odpowiednią wersję dla swojego systemu operacyjnego i wersji Pythona.
Instalacja WxPython dla Windows http://www.wxpython.org/download.php
2. Używamy wxPythona przez importowanie tej biblioteki w każdym kodzie źródłowym pytona:
Ale od początku:
wxPython składa się z 5 podstawowych modułów:
Moduł Controls dostarcza wzorców podstawowych komponentów przy tworzeniu aplikacji (tzw. widgetów) np.: button, toolbar, notebook. Nazywamy je popularnie „kontrolkami”.
Moduł Core dostarcza podstawowych klas: Object (matka wszystkich klas), Sizers (layouty widgetów), Events (zdarzenia), oraz klasy elementarnej grafiki jak Prostokąty (Rectangle) czy punkt (Point).
GDI (graphics device interface) to zbiór klas pozwalających rysowad na widgetach. Mamy to klasy do manipulacji czcionkami (Font), kolorami (Colours), Brushes, Pens i Images (pędzel, czy obrazy).
Misc to zbiór różnego typu klas i funkcji np. do logowania, konfiguracji aplikacji, ustawieo systemowych, wyświetlaniem czy sterowaniem aplikacją.
Windows to grupa klas do tworzenia okna: formatek, okien czy całej aplikacji: Scrolled Window, Dialog, Panel czy Frame.
Podstawowe Widgety:
Widgety górnego poziomu (występuję zależnie od siebie):
Kontenery (zawierające inne widgety):
Dynamiczne widgety:
Statyczne widgety:
Inne:
Dziedziczenie:
Każde okno może reagowad na zdarzenia – a więc Button także.
Klikając na przycisk (button) wywołujemy zdarzenie: wx.EVT_COMMAND_BUTTON_CLICKED Aby widget mógł reagowad na zdarzenia musi dziedziczyd własności po klasie wx.EvtHandler.
Krok 1. Pierwszy program Efektem kodu:
Będzie okno:
Interpretacja kodu:
Linia 1: „import wx” znaczenie: importujemy pakiet WxPython
Linia 2: „app = wx.App()” znaczenie: każdy obiekt wxPython musi mied przynajmniej jeden obiekt typu App
Linia 3: frame = wx.Frame(None, -1, 'simple.py') znaczenie: obiekty typu wx.Frame to typ kontenera, ponieważ nie ma nadrzędnego sobie kontenera bo jest głównym kontenerem aplikacji to wpisujemy „None” w miejscu odwołania do
„rodzica”. Trzeci argument ‘simple.py’ oznacza, że w tytule okienka będzie taki wlasnie napis.
Linia 4: frame.Show() znaczenie: musimy pokazad okno na ekranie
Linia 5: app.MainLoop() znaczenie: wyświetlanie dzieje się w pętli, dopóki innym zdarzeniem nie przerwiemy wyświetlania okna.
Wx.Frame jest typem kontenera który nie zawiera ramek (Frame) czy dialogów (Dialog). Sklada się z paska tytułu, obszarów bocznych i środkowego do umieszczania komponentów.
Konstruktor klasy dla wx.Frame:
Wx.DEFAULT_FRAME_STYLE to zbiór możliwych stylów okna:
Wx.MINIMIZE_BOX, wx_MAXIMIZE_BOX, wx_RESIZE_BORDER, wx_SYSTEM_MENU, wx.CAPTION, wx_CLOSE_BOX, wx_CLIP_CHILDREN.
Krok 1a. Mała zmiana Wykonanie kodu:
Praktycznie niczym się nie różni, chod w szczegółach się okaże, że nie można tego okna „zminimalizowad”.
Krok 2. Ustalimy teraz rozmiar wyświetlanego okna.
Wykonanie kodu:
Spowoduje powstanie okna o rozmiarach: 250 x 200 pikseli.
Możemy także sterowad pozycją w której okno będzie wyświetlone na ekranie:
Np. kod:
Wyświetli okno (lewy górny róg okna) w pozycji 800 x 250.
Zaś kod:
Wyświetli okno dokładnie na środku ekranu.
Krok 3: Komunikacja z użytkownikiem.
Napiszemy aplikację która tworzy okienko z dwoma przyciskami (button) i polem tekstowym w którym wyświetlana jest aktualna wartośd licznika, którego możemy zmniejszad bądź zwiększad klikając na przyciski „+” i „-”.
Kod:
import wx
class LeftPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN) self.text = wx.StaticText(self, -1, '0', (140, 60))
button1 = wx.Button(self, -1, '+', (10, 10)) button2 = wx.Button(self, -1, '-', (10, 60))
self.Bind(wx.EVT_BUTTON, self.OnPlus, id=button1.GetId()) self.Bind(wx.EVT_BUTTON, self.OnMinus, id=button2.GetId()) def OnPlus(self, event):
value = int(self.text.GetLabel()) value = value + 1
self.text.SetLabel(str(value)) def OnMinus(self, event):
value = int(self.text.GetLabel()) value = value - 1
self.text.SetLabel(str(value)) class Communicate(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(280, 200)) panel = wx.Panel(self, -1)
leftPanel = LeftPanel(panel, -1) hbox = wx.BoxSizer()
hbox.Add(leftPanel, 1, wx.EXPAND | wx.ALL, 2) panel.SetSizer(hbox)
self.Centre() self.Show(True) app = wx.App()
Communicate(None, -1, 'licznik') app.MainLoop()
Ćwiczenia: Spróbuj dodać jeszcze jeden przycisk, który będzie zerował wartość licznika.
Krok 4. Tworzenie Menu
Aby dodad menu do naszej aplikacji potrzebujemy 3 elementów:
1. wx.MenuBar 2. wx.MenuItem 3. wx.Menu
Wykonanie następującego kodu:
Kod:
import wx
class SimpleMenu(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(250, 150)) menubar = wx.MenuBar()
file = wx.Menu()
file.Append(-1, 'koniec', 'koniec programu') menubar.Append(file, '&Plik')
self.SetMenuBar(menubar) self.Centre()
self.Show(True) app = wx.App()
SimpleMenu(None, -1, 'proste menu') app.MainLoop()
To okno:
Gdzie póki co nic się nie dzieje.
Jeśli chcemy utworzyd cały pasek:
Wystarczy napisad następujący kod:
Krok 5: obsługa zdarzeo
Aby napisad taki program wystarczy użyd kodu:
import wx
class MenuExample(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(250, 150)) menubar = wx.MenuBar()
file = wx.Menu()
quit = wx.MenuItem(file, 1, '&Quit\tCtrl+Q') quit.SetBitmap(wx.Bitmap('icons/exit.png')) file.AppendItem(quit)
self.Bind(wx.EVT_MENU, self.OnQuit, id=1) menubar.Append(file, '&File')
self.SetMenuBar(menubar) self.Centre()
self.Show(True) def OnQuit(self, event):
self.Close() app = wx.App()
MenuExample(None, -1, '') app.MainLoop()
Klikając opcję „Quit” wywołujemy zdarzenie: wx.EVT_MENU, i wywołujemy metodę o nazwie onQuit() która zamyka aplikację:
Każda taka opcja w menu (MenuItem) może byd elementem typu:
normal item
radio item
check item
np.: self.shst = view.Append(ID_STAT, 'Show statubar', 'Show Statusbar', kind=wx.ITEM_CHECK)
Potem sprawdzenie czy opcja jest włączona czy wyłączona
def ToggleStatusBar(self, event):
if self.shst.IsChecked():
self.statusbar.Show() else:
self.statusbar.Hide()
Toolbar
CreateToolBar(long style=-1, int winid=-1, String name=ToolBarNameStr)
Krok 6: tworzymy aplikację z menuToolbarem z dwoma przyciskami (2 obrazki):
Czego efekt będzie następujący:
Krok 7: okno dialogowe.
Wykonaniem następującego kodu:
Będzie aplikacja:
Klikając w przycisk: uruchomi się okno:
Wybierając opcję „Tak” zamykamy aplikację, wybierając „Nie” wracamy do aplikacji.
Krok 8: Okno dialogowe – częśd II
Czasami chcemy sprawdzid jakie zdarzenia kliknięto „X” do zamknięcia okienka i zapobiec temu. Chcemy np.
zapytad użytkownika wtedy czy na pewno chce zamknąd okno czy jednak nie. Służą do tego okienka dialogowe.
Gdy pojawi się okno:
I klikniemy: wyświetli się okno z pytaniem
Jeśli teraz klinkiemy „Tak” program się zakooczy (okno się zamknie). Jeśli klikniemy „Nie” wrócimy do głównego okna.
Kod programu który to realizuje wygląda następująco:
Linia nr 5:
Tutaj mówimy, iż okno główne ma mied obsługę zdarzeo na zamknięcie okna i wtedy jeśli przechwycone zostanie takie zdarzenie ma zostad wykonana funkcja OnClose().
Jej ciało (a więc instrukcje, które mają się wykonad gdy to zdarzenie nastąpi) wygląda następująco:
A wiec tworzymy obiekt o nazwie „dial”. Będzie on oknem typu „MessageDialog”, z pytaniem w środku okna „Jesteś pewien ?”, z tytułem „Pytanie” i możliwymi przyciskami: „Tak” i „Nie”. Jest tu także zaznaczone, że domyślnie ma byd zaznaczona opcja „Nie” i że ma byd w takim okienku inkona „pytajnika”.
Aby nie można było się przełączyd na okienko głowne zanim się nie dokona jakiegoś wyboru należy użyd funkcji „ShowModal()”.
Jeśli użyjemy instrukcji:
ret = dial.ShowModal()
to potem będziemy mogli sprawdzid która opcja „tak” czy „nie” została wybrana przez użytkownika za pomocą następującego kodu:
if ret == wx.ID_YES:
self.Destroy() else:
event.Veto()
To jest równoważne z zapisem:
if ret == wx.ID_YES:
self.Destroy() elif ret == wx.ID_NO:
event.Veto() Krok 9: Zdarzenia w pythonie
Napiszmy aplikację która tworzy okienko i sprawdza pozycję startową okienka, którego lokalizację zmieniamy przeciągając myszą okno z pozycji A do pozycji B. Za każdym razem zostanie wówczas odczytana aktualna pozycja lewego górnego okna programu i wyświetlona na ekranie wartości pozycji na osi X i Y.
Aby sprawdzid zmianę lokalizacji komponentu użyjemy zdarzenia wx.MoveEvent i konkretnie klasy wx.EVT_MOVE.
Komendą którą zwiążemy jakiś komponent z obsługą zdarzeo i pokażemy funkcję która ma byd wywołana gdy to zdarzenie nastąpi będzie:
self.Bind(wx.EVT_MOVE, self.OnMove)
Teraz musimy jeszcze wskazad co ma się stad w ciele funkcji OnMove():
def OnMove(self, event):
x, y = event.GetPosition()
Efekt:
Gdy teraz przesuniemy okno w inne miejsce….
Krok 10: Obsługa klawiatury:
Reakcja tylko na określony klawisz jest możliwa w pytonie w prosty sposób:
1. Najpierw pobieramy kod klawisza: keycode = event.GetKeyCode()
2. Sprawdzamy czy klawisz to ten o który nam chodzilo: if keycode == wx.WXK_ESCAPE:
Jak widad sprawdzenie czy wciśnięto klawisz ESCAPE wykonane jest w następujący sposób:
Gdybyśmy teraz chcieli sprawdzid i cos innego zrobid gdy z klawiatury użytkownik wciśnie klawisz np. A lub a wystarczy dodad fragment kodu:
Krok 11: Message Dialogi
To pozwala stworzyd aplikację:
Gdzie klikając na każdy z przycisków: „info”, „error”, „question” czy „alert” dostajemy inne okienka z komunikatami:
Dla info:
Dla „error”:
Dla „question”:
I dla „alert”:
Flaga znaczenie
wx.OK Show OK. button
wx.CANCEL show Cancel button
wx.YES_NO show Yes, No buttons
wx.YES_DEFAULT make Yes button the default
wx.NO_DEFAULT make No button the default
wx.ICON_EXCLAMATION show an alert icon
wx.ICON_ERROR show an error icon
wx.ICON_HAND same as wx.ICON_ERROR
wx.ICON_INFORMATION show an info icon
wx.ICON_QUESTION show a question icon