Zapisz jako PDF

Transkrypt

Zapisz jako PDF
W tym rozdziale zaprezentuję krótko widgety dostępne w wxPythonie, związane z nimi style i eventy.
Spis treści
1 Wyświetlanie tekstu
2 Wprowadzanie tekstu
3 Przyciski
4 Suwaki
5 Spinner
6 CheckBoxy
7 RadioButtony
8 ListBoxy
9 Listy rozwijane
Wyświetlanie tekstu
Do wyświetlania tekstu stosuje się obiekty klasy wx.StaticText. Można ustawiać kolor tekstu (metoda
SetForegroundColour) i rodzaj czcionki (metoda SetFont). Konstruktor opisywanej klasy wygląda
następująco:
wx.StaticText(parent, id, label, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=, name="staticText")
Konstruktory większości widgetów w wxPythonie są podobne - na pierwszym koniecznym parametrze
przekazywany jest rodzic czyli kontener w którym ma być wyświetlany tworzony obiekt, następne
parametry są opcjonalne: id - numer identyfikacyjny przypisywany obiektowi, jeśli nie podamy nic,
podamy -1 lub wx.ID_ANY to Python sam przypisze numer id tak aby był on unikalny na poziomie
kontenera (jeśli numery id podajemy sami to powinny być one dodatnie i unikalne na poziomie
kontenera), dalej występuje parametr label mówiący co ma być wypisane na ekranie, następnie dwie
krotki opisują pozycję widgetu we współrzędnych ramki i jego wielkość, liczba całkowita (style)
opisująca w formie maski bitowej styl (możliwe wartości to wx.ALIGN_CENTER, wx.ALIGN_RIGHT,
wx.ALIGN_LEFT - do ustawiania tekstu wewnątrz widgetu i wx.ST_NO_AUTORESIZE - do wyłączania
zmieniania rozmiaru widgetu po wywołaniu SetLabel) i na koniec można podać parametr name czyli
nazwę po której będziemy mogli później znaleźć tworzony obiekt.
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
txt = wx.StaticText(parent = panel, id = wx.ID_ANY, label =
"przykładowy tekst", pos = (, ), size = (100, 200), style = , name = 'tekst')
txt.SetForegroundColour('red')
font = wx.Font(18, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
txt.SetFont(font)
self.Show()
app = wx.App()
MyFrame()
app.MainLoop()
Przy pomocy metody SetLabel(self, string) można ustawić zawartość okna, a pobrać ją metodą
GetLabel(self)
Wprowadzanie tekstu
Do wprowadzania tekstu służą obiekty klasy wx.TextCtrl, wpisywany tekst może być ukrywany jako
hasło. Konstruktor tej klasy wygląda następująco:
wx.TextCtrl(parent, id, value = "", pos = wx.DefaultPosition, size =
wx.DefaultSize, style = , validator = wx.DefaultValidator, name =
wx.TextCtrlNameStr)
W stosunku do poprzedniego obiektu parametr label został zastąpiony parametrem value (również
metody pobierające i ustawiające będą się nazywały SetValue(self, string) i GetValue(self)).
Validatory służą do sprawdzania czy podane przez użytkownika dane są poprawne - zostaną one
opisane w oddzielnym rozdziale. W tym przypadku możliwe style są inne: do zarządzania pozycją
wpisanego tekstu służą style wx.TE_CENTER, wx.TE_LEFT, wx.TE_RIGHT, do maskowania
wpisywanego tekstu jako hasło wx.TE_PASSWORD, aby uniemożliwić wpisywanie do danego widgeta
należy podać styl wx.TE_READONLY, w końcu występują dwa style opisujące działanie związane z
wciśnięciem klawisza enter lub tab gdy jesteśmy w okienku, gdy podamy styl
wx.TE_PROCESS_ENTER po wciśnięciu klawisza enter zostanie zgłoszony event
wx.EVT_TEXT_ENTER, a ustawienie stylu wx.TE_PROCESS_TAB spowoduje, że wciśnięcie taba
podczas wpisywania do widgeta spowoduje wprowadzenie tabulatora do tekstu zamiast
standardowego przechodzenia focusem do kolejnego okienka. Gdy do wx.TextCtrl zostanie
wprowadzony tekst jest generowany event wx.EVT_TEXT. Metodą AppendText(string) można dodać
tekst do już wpisanego (na koniec, na początek dodaje się metodą WriteText(string)), Clear()
powoduje czyszczenie okna, GetRange(from, to) zwraca tekst znajdujący się na pozycjach od from do
to, GetSelection() zwraca krotkę z początkowym i końcowym indeksem zaznaczenia,
GetStringSelection() zwraca zaznaczenie jako napis, a SetSelection(from, to) zaznacza tekst na
pozycjach od from do to. Metody GetValue() i SetValue(string) zwracają i ustawiają cały napis. Tekst
można usuwać metodą Remove(from, to) i zamieniać na inny napis metodą Replace(from, to, string).
Prosty przykład:
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
txt = wx.TextCtrl(parent = panel, id = 11, value = u"przykladowy
tekst", size = (200, 50), style = wx.TE_PROCESS_ENTER)
self.Bind(wx.EVT_TEXT, self.OnText, txt)
self.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter, txt)
self.Show()
def OnText(self, evt):
wx.MessageBox(u"Zmienione tekst, aktualna wartość: " +
self.FindWindowById(evt.GetId()).GetValue())
def OnTextEnter(self, evt):
wx.MessageBox(u"Wciśnięto klawisz enter")
app = wx.App()
MyFrame()
app.MainLoop()
Widgety można wyszukiwać także po nazwie metodą FindWindowByName i po labelce jeśli ją
posiadają metodą FindWidnowByLabel.
Przyciski
Przyciski w wxPythonie to obiekty klasy wx.Button, konstruktor tej klasy wygląda następująco:
wx.Button(parent, id, label, pos = wx.DefaultPosition, size = wx.DefaultSize,
style = , validator = wx.DefaultValidator, name = "button")
Przycisk po kliknięciu go wysyła event wx.EVT_BUTTON. Prosty przykład użycia:
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
btn = wx.Button(panel, label = u"przykladowy tekst")
self.Bind(wx.EVT_BUTTON, self.OnButton, btn)
self.Show()
def OnButton(self, evt):
wx.MessageBox(u"Wciśnięto przycisk")
app = wx.App()
MyFrame()
app.MainLoop()
Innym rodzajem przycisku jest wx.ToggleButton, który ma dwa stany wciśnięty lub nie - działa
podobnie jak checkbox, jego stan można pobrać przy pomocy GetValue, a ustawić SetValue, wysyła
on też inne event po przyciśnięci - patrz przykład:
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
btn = wx.ToggleButton(panel, label = u"przykladowy tekst")
self.Bind(wx.EVT_TOGGLEBUTTON, self.OnButton, btn)
self.Show()
def OnButton(self, evt):
wx.MessageBox(u"Przycisk " + (u"wciśnięty" if
self.FindWindowById(evt.GetId()).GetValue() else u"nie wciśnięty"))
app = wx.App()
MyFrame()
app.MainLoop()
Suwaki
Do pobierania od użytkownika danych, które musi wpisać są liczbami całkowitymi z pewnego
przedziału można wykorzystać suwaki reprezentowane przez klasę wx.Slider. Konstruktor tej klasy
wygląda następująco:
wx.Slider(parent, id, value, minValue, maxValue, pos = wxDefaultPosition,
size = wx.DefaultSize, style = wx.SL_HORIZONTAL, validator =
wx.DefaultValidator, name = "slider")
Parametr value oznacza początkową wartość suwaka, a jego zakres jest określany przez minValue i
maxValue. Dostępne są następujące style: wx.SL_HORIZONTAL i wx.SL_VERTICAL ustawiające
kierunek suwaków, wx.SL_LEFT, wx.SL_RIGHT,i wx.SL_TOP - określające gdzie należy narysować
kreseczki oznaczające kolejne wartości, podanie stylu wx.SL_LABELS powoduje pojawienie się
informacji jaka jest największa, najmniejsza i aktualnie zaznaczona wartość i wx.SL_AUTOTICKS,
którego ustawienie powoduje pojawienie się kreseczek, których gęstość można ustawić metodą
SetTickFreq(n, pos) - gdzie n to wartość kroku między kreseczkami, a drugi parametr nie jest
używany. Do pobierania i ustawiania zakresu służą metody GetRange() i SetRange(min, max). Gdy
focus jest na sliderze, to jego wartość można zmieniać przy pomocy strzałek - o ile wartość jest
wtedy zmieniana można ustawić metodą SetLineSize(n) i pobrać GetLineSize(), a także przy pomocy
klawiszy PgUp i PgDn - odpowiednie metody to: SetPageSize(n) i GetPageSize(). W końcu pobrać i
ustawić wartość można przy pomocy GetValue() i SetValue(n). Eventy generowane przez tą klasę to
EVT_SCROLL, EVT_SCROLL_BOTTOM i EVT_SCROLL_TOP generowane gdy użytkownik przesunie
slider do odpowiedniego końca, EVT_SCROLL_LINEDOWN, EVT_SCROLL_LINEUP,
EVT_SCROLL_PAGEDOWN, EVT_SCROLL_PAGEUP generowane gdy użytkownik zmienia wartość
slidera przy pomocy klawiszy, EVT_SCROLL_THUMBRELEASE, EVT_SCROLL_THUMBTRACK generowane gdy zakończymy przesuwanie slidera i podczas przesuwania. Przykład:
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
btn = wx.Slider(panel, minValue = , maxValue = 200, value = 100, size
= (200, 50), style = wx.SL_HORIZONTAL|wx.SL_LABELS|wx.SL_TOP)
self.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnThumbRelease, btn)
self.Show()
def OnThumbRelease(self, evt):
wx.MessageBox(u"Przesuwanie zakończone warość " +
str(self.FindWindowById(evt.GetId()).GetValue()))
app = wx.App()
MyFrame()
app.MainLoop()
Spinner
Spinner pozwala ustawiać wartości z pewnego dyskretnego zakresu przy pomocy strzałek i pola typu
TextCtrl, konstruktor wygląda następująco:
wx.SpinCtrl(parent, id = -1, value = wx.EmptyString, pos =
wx.DefaultPosition, size = wx.DefaultSize, style = wx.SP_ARROW_KEYS, min = ,
max = 100, initial = , name = "wxSpinCtrl")
Gdy wartość zostanie zmieniona generowany jest event EVT_SPINCTRL, jeśli zmieniany jest tekst w
TextCtrl to generowany jest EVT_TEXT, styl wx.SP_ARROW_KEYS pozwala na zmienianie wartości
przy pomocy strzałek do góry i dół, a wx.SP_WRAP powoduje, że po osiągnięciu maksymalnej
wartości przechodzimy do wartości najmniejszych. Prosty przykład:
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
spin = wx.SpinCtrl(panel, min = , max = 200, initial = 100, style =
wx.SP_ARROW_KEYS|wx.SP_WRAP)
self.Bind(wx.EVT_SPINCTRL, self.OnSpin, spin)
self.Bind(wx.EVT_TEXT, self.OnText, spin)
self.Show()
def OnSpin(self, evt):
wx.MessageBox(u"Zmieniono warość na " +
str(self.FindWindowById(evt.GetId()).GetValue()))
def OnText(self, evt):
wx.MessageBox(u"Wpisano coś do TextCtrl")
app = wx.App()
MyFrame()
app.MainLoop()
CheckBoxy
CheckBoxy pozwalają wybrać użytkownikowi pewne opcje, mają one dwa stany - zaznaczony i nie
zaznaczony. Konstruktory wygląda następująco:
wx.CheckBox(parent, id, label, pos = wx.DefaultPosition, size =
wx.DefaultSize, style = , name = "checkBox")
Przy zmianie stanu zgłaszany jest event EVT_CHECKBOX. Klasa wx.CheckBox udostępnia metody
GetValue, SetValue i IsChecked. Przykład:
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
for i in range(5):
wx.CheckBox(panel, label = 'Opcja ' + str(i), id = 100 + i, pos =
(, 25 * i))
self.Bind(wx.EVT_CHECKBOX, self.OnCheck, id = 100, id2 = 104)
self.Show()
def OnCheck(self, evt):
win = self.FindWindowById(evt.GetId())
wx.MessageBox(win.GetLabel() + u' została ' + ('zaznaczona' if
win.IsChecked() else 'odznaczona'))
app = wx.App()
MyFrame()
app.MainLoop()
RadioButtony
Jeśli chcemy aby użytkownik wybrał dokładnie jedną z niewielkiej liczby opcji można to zrealizować
za pomocą RadioButtonów połączonych w grupę, konstruktor opisywanej klasy jest następujący:
wx.RadioButton(parent, id, label, pos = wx.DefaultPosition, size =
wx.DefaultSize, style = , validator = wx.DefaultValidator, name =
"radioButton")
<source>
Utworzenie obiektu o stylu wx.RB_GROUP rozpoczyna nową grupę i wszystkie
utworzone obiekty do czasu kolejnego z takim stylem będą należały do jednej
grupy, a więc dokładnie jeden z nich będzie wybrany. Przy zmianie stanu na
zaznaczony generowany jest event EVT_RADIOBUTTON. Przykład zastosowania:
<source lang='python'>
# -*- coding: utf-8 -*import wx
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
for i in range(5):
wx.RadioButton(panel, label = 'Opcja ' + str(i), id = 100 + i,
pos = (, 25 * i))
self.Bind(wx.EVT_RADIOBUTTON, self.OnCheck, id = 100, id2 = 104)
self.Show()
def OnCheck(self, evt):
win = evt.GetEventObject()
wx.MessageBox(win.GetLabel() + u' została zaznaczona')
app = wx.App()
MyFrame()
app.MainLoop()
Ten przykład pokazuje przy okazji, że z eventu można bezposrednio uzyskać obiekt który go
wygenerował przy pomocy metody GetEventObject(). Do sprawdzania stanu radioboxa można
wykorzystać metodę GetValue()
ListBoxy
ListBoxy są stosowane jeśli użytkownik może wybrać jedną lub więcej opcji z podanej listy.
Konstruktor wygląda następująco:
wx.ListBox(parent, id, pos = wx.DefaultPosition, size = wx.DefaultSize,
choices = None, style = , validator = wx.DefaultValidator, name = "listBox")
Na paramer choices podajemy listę opcji z których użytkownik może wybierać. Styl wx.LB_SINGLE
dopuszcza tylko pojedynczy wybór, wx.LB_MULTIPLE wybranie wielu opcji, a wx.LB_EXTENDED
wybór wielu opcji ale następujących po sobie przy pomocy klikania z wciśniętym klawiszem shift.
ListBox może być wyposażony w scrollbar, jego występowanie opisują następujące style:
wx.LB_ALWAYS_SB - zawsze jest wyświetlany, wx.LB_HSCROLL - pojawia się poziomy scroll,
wx.LB_NEEDED_SB - domyślny styl, pioinowy scrollbar pojawia się tylko gdy jest potrzebny, styl
wx.LB_SORT powoduje, że wyświetlana lista opcji jest posortowana alfabetycznie. Kiedy element na
liście zostaje wybrany zgłaszany jest event EVT_LISTBOX, a po dwukrotnym kliknięciu na listę
EVT_LISTBOX_DCLICK. Opisywana klasa udostępnia metody do dodawania, usuwania i pobierania
opcji z listy: Append(item), Clear(), Delete(n), GetCount(), InsertItems(items, pos) i Set(choices), a
także do ustawiania i pobierania elementów zaznaczonych: GetSelection(), SetSelection(n, select),
GetStringSelection(), SetStringSelection(string, select), GetSelections(), Deselect(n) i Selected(n) ich nazwy dość jasno mówią co dane metody robią. Prosty przykład:
# -*- coding: utf-8 -*import wx
import string
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
self.last = 'A'
self.listBox = wx.ListBox(panel, choices = [self.last], size = (-1,
100), style = wx.LB_MULTIPLE)
self.Bind(wx.EVT_LISTBOX, self.OnList, self.listBox)
self.Show()
def OnList(self, evt):
win = evt.GetEventObject()
opcje = [win.GetString(index) for index in win.GetSelections()]
wx.MessageBox(u'zaznaczone opcje : ' + string.join(opcje))
self.last = chr(ord(self.last) + 1)
self.listBox.Append(self.last)
app = wx.App()
MyFrame()
app.MainLoop()
Listy rozwijane
W wxPythonie są dwa rodzaje list rozwijanych - wx.Choice pozwalająca wybrać opcję z podanych i
wx.ComboBox dodatkowo pozwalająca wpisać dowolną wartość, ich konstruktory to:
wx.Choice(parent, id, pos = wx.DefaultPosition, size = wx.DefaultSize,
choices = wx.EmptyList, style = , validator = wx.DefaultValidator, name =
"choice")
wx.ComboBox(parent, id, value = "", pos = wx.DefaultPosition, size =
wx.DefaultSize, choices = wx.EmptyList, style = , validator =
wx.DefaultValidator, name = "comboBox")
W przeciwieństwie do obiektów klasy wx.Choice obiektom klasy wx.ComboBox można ustawić
wartość początkową (obiekty wx.Choice mają na początku pustą wartość). Gdy opcja zostanie
wybrana obiekty generują odpowiednio eventy: EVT_CHOICE i EVT_COMBOBOX. Jeśli utworzymy
ComboBoxa ze stylem wx.CB_READONLY nie można będzie wprowadzać własnych opcji, a ze stylem
wx.CB_SORT powoduje, że elementy na liście będą posortowane alfabetycznie. Prosty przykład:
# -*- coding: utf-8 -*import wx
import string
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
comboBox = wx.ComboBox(panel, choices = ['A', 'B', 'C'], size = (-1,
100))
self.Bind(wx.EVT_COMBOBOX, self.OnCombo, comboBox)
self.Bind(wx.EVT_TEXT, self.OnCombo, comboBox)
self.Show()
def OnCombo(self, evt):
wx.MessageBox(u'wybrana opcja : ' + evt.GetEventObject().GetValue())
app = wx.App()
MyFrame()
app.MainLoop()
"Programowanie dla Fizyków Medycznych"

Podobne dokumenty