wxApp има няколко метода които трябва да се дефинират или извикат:
Да видим как изглежда казаното досега като код:
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(parent = None, title = "My own frame")
frame.Show()
self.SetTopWindow(frame)
return True
class MyFrame(wx.Frame):
def __init__(self, parent, title, id = -1):
wx.Frame.__init__(self, parent, id, title)
panel = wx.Panel(parent = self)
self.greeting = wx.StaticText(parent = panel, pos = (20, 20), label = "Hello pythoneers!")
app = MyApp()
app.MainLoop()
За да реагира на действията на потребителя, wxPython използва предварително зададени възможни събития( например натискане на бутон или преместване на прозореца) с които можете да асоциирате ваши функции които да обработват по желания от вас начин събитието. Това става като "свържете" някой прозорец с дадено събитие, което е възникнало в него, и с вашата функция която ще го обработи
За удобство събитията не се виждат само от прозореца в който са възникнали, а и от всички прозорци нагоре в родителското дърво. Това означава че ако в панел имате няколко бутона, не е нужно събитието "натискане на бутон" да се прехваща във всеки бутон, може директо да ги прехванете в панела.
Това става като извикате метода Bind на прозореца в който искате да прехванете събитието и му подадете типа събитие, функцията която ще се извика, и източника на събитието
В конструктора на MyFrame добавяме:
menuBar = wx.MenuBar()
menu = wx.Menu()
menu.Append(self.ID_Exit, "E&xit")
menuBar.Append(menu, "&File")
menu = wx.Menu()
menu.Append(self.ID_About, "&About")
menuBar.Append(menu, "&Help")
self.SetMenuBar(menuBar)
Свързваме менютата с наши функции които искаме да се изпълнят когато менюте се избере:
self.Bind(wx.EVT_MENU, self.OnExit, id = self.ID_Exit)
self.Bind(wx.EVT_MENU, self.OnAbout, id = self.ID_About)
И добавяме handler`ите ни:
def OnExit(self, event):
answer = wx.MessageBox("Do you really want to quit?", "Confirm", style = wx.YES_NO | wx.ICON_QUESTION)
if answer == wx.YES: self.Close()
def OnAbout(self, event):
wx.MessageBox("wxPython greeter program", "About", style = wx.OK)
При слагането на повече контроли в един прозорец става малко трудно да ги наредите всички така че да не си пречат. Указването на точна позиция(в координати) на всеки е дейност, достойна за наказание в програмисткия ад. Едно решение на проблема са така наречените sizers
Sizer-ите разчитат на това че в повечето случаи разположението на обектите в прозореца следва прости геометрични правила като например в колона, редица или таблица. Използването им е съвсем просто - при създаване на прозорец създавате и sizer който ще отговаря за него, добавяте всички деца на прозореца в sizer-а и накрая не забравяте да кажете на прозореца кой му е sizer-a. След това sizer-а автоматично поема отговорността за разположението на обектите в прозореца
При добавяне на обекти в sizer-а можете да укажете дали обекта ще се разширява при разширяване на целия прозорец и в какво съотношение в сравнение с останалите обекти в прозореца
Засега прозореца в приложението ни е много пуст и на самотния низ му е много скучно, а и му е писнало да поздравява само едни и същи хора. Нека му разнообразим съществуването: ще добавим поле в което да се казва кого ще поздравява програмата ни и бутон с който да поздравим въведеното същество
За целта създаваме BoxSizer в конструктора на MyFrame и добавяме текста и новите контроли в него
self.textField = wx.TextCtrl(panel, -1)
self.greetButton = wx.Button(panel, ID_Greet, "Greet")
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
buttonSizer.Add(wx.StaticText(parent = panel, label = "Enter name:"), 0, wx.ALL, 10)
buttonSizer.Add(self.textField, 1, wx.ALL | wx.EXPAND, 10)
buttonSizer.Add(self.greetButton, 0, wx.ALL, 10)
panelSizer = wx.BoxSizer(wx.VERTICAL)
panelSizer.Add(self.greeting, 1, wx.ALL | wx.EXPAND | wx.CENTRE, 10)
panelSizer.Add(buttonSizer, 0, wx.ALL | wx.EXPAND, 10)
panel.SetSizer(panelSizer)
panel.Fit()
self.Bind(wx.EVT_BUTTON, self.OnGreet, self.greetButton)
frameSizer = wx.BoxSizer(wx.VERTICAL)
frameSizer.Add(panel, 1, wx.EXPAND)
self.SetSizerAndFit(frameSizer)
Остана да добавим handler-а за новия бутон:
def OnGreet(self, event):
name = self.textField.GetValue()
if len(name) == 0:
wx.MessageBox("Enter a name to greet first", "Error", style = wx.OK | wx.ICON_EXCLAMATION)
return
self.greeting.SetLabel("Hello %s!" % name)
self.Refresh()
self.Update()
Честито, вече си имаме прозорче с което можем да поздравяваме когото ни хареса:)