= How to separate Gui and logic (Phoenix) = '''Keywords :''' Gui, Frame, Events handler, Widget. . <<TableOfContents>> -------- = Introduction : = I was sometimes ago playing around how to interact with classes and their methods. I thought it will be better to share something. Here is simple example to show how to work with methods from another class. This can be helpful in separating GUI from logic (if you don't like xml/xrc). Classes and interactions : this can be good in separating GUI from Logic Also can be used to separate different classes doing different jobs. Programmed by Stephen Mtangoo Email : babaeliya@hotmail.com (United Republic of Tanzania). Licenced under same LICENCE as wxpython. Anybody can make it better, but don't change the main meaning / theme : Just improvements are allowed. -------- = Demonstrating : = __'''''Tested''' py3.x, wx4.x and Win10. ''__ Are you ready to use some samples ? ;) Test, modify, correct, complete, improve and share your discoveries ! (!) -------- == First example == {{attachment:img_sample_one.png}} '''ICON''' file : [[attachment:wxwin.ico]] {{{#!python # sample_one.py import wx # class MyFrame # class MyEvents # class MyApp #--------------------------------------------------------------------------- class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title) self.SetIcon(wx.Icon("wxwin.ico")) #------------ self.functions = MyEvents(self) self.panel = wx.Panel(self, -1) #------------ # Add two buttons and text control. self.text = wx.TextCtrl(self.panel, -1) self.text.SetLabel("Hello world !") self.text.SetForegroundColour("white") self.text.SetBackgroundColour(wx.BLACK) self.button1 = wx.Button(self.panel, -1, "Red Colour") self.button2 = wx.Button(self.panel, -1, "Green Colour") #------------ # Bind events to widgets. self.Bind(wx.EVT_BUTTON, self.functions.OnRed, id = self.button1.GetId()) self.Bind(wx.EVT_BUTTON, self.functions.OnGreen, id = self.button2.GetId()) #------------ # Add them to sizer [define it first to prevent python # automatic detector to find you red handed]. main = wx.BoxSizer(wx.VERTICAL) main.Add(self.text, 1, wx.EXPAND|wx.ALL, 1) #------------ # Add buttons in separate sizer. sub_main = wx.BoxSizer(wx.HORIZONTAL) sub_main.Add(self.button1, 0, wx.EXPAND| wx.ALL, 5) sub_main.Add(self.button2, 0, wx.EXPAND| wx.ALL, 5) main.Add(sub_main, 0, wx.EXPAND| wx.ALL, 5) #------------ # Set sizers to Frame through panel. self.panel.SetSizer(main) self.panel.Layout() #--------------------------------------------------------------------------- class MyEvents(): def __init__(self, parent): self.gui = parent #----------------------------------------------------------------------- def OnRed(self, evt): self.gui.text.SetBackgroundColour("Red") dlg = wx.MessageDialog(self.gui, "Changed colour ! Click on the window to see !", "Successful", style = wx.ICON_INFORMATION| wx.OK) dlg.ShowModal() if dlg.ShowModal == wx.ID_OK: dlg.Destroy() def OnGreen(self, evt): self.gui.text.SetBackgroundColour(wx.GREEN) dlg = wx.MessageDialog(self.gui, "Changed colour ! Click on the window to see !", "Successful", style = wx.ICON_INFORMATION| wx.OK) dlg.ShowModal() if dlg.ShowModal == wx.ID_OK: dlg.Destroy() #--------------------------------------------------------------------------- class MyApp(wx.App): def OnInit(self): #------------ frame = MyFrame(None, -1, "Classes and interactions") self.SetTopWindow(frame) frame.Show(True) return True #--------------------------------------------------------------------------- def main(): app = MyApp(redirect=False) app.MainLoop() #--------------------------------------------------------------------------- if __name__ == "__main__" : main() }}} -------- == Second example == {{attachment:img_sample_two.png}} '''ICON''' file : [[attachment:wxwin.ico]] {{{#!python # sample_two.py import wx # class MyFrame # class MyEventsHandler # class MyApp #--------------------------------------------------------------------------- class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, -1, title=title) self.SetIcon(wx.Icon("wxwin.ico")) #------------ self.frmPanel = wx.Panel(self) self.frmPanel.BackgroundColour = (200, 240, 250) # light blue #------------ # Add another panel and some buttons self.colourPnl = wx.Panel(self.frmPanel) self.colourPnl.SetBackgroundColour(wx.Colour('GREY')) #------------ self.redBtn = wx.Button(self.frmPanel, label='Red') self.greenBtn = wx.Button(self.frmPanel, label='Green') self.exitBtn = wx.Button(self.frmPanel, label='Exit') #------------ # Add them to sizer. colorPnlAndBtn_vSizer = wx.BoxSizer(wx.VERTICAL) colorPnlAndBtn_vSizer.Add(self.colourPnl, 1, wx.EXPAND|wx.ALL, 1) # Add buttons in their own sizer btn_hSizer = wx.BoxSizer(wx.HORIZONTAL) btn_hSizer.AddStretchSpacer() btn_hSizer.Add(self.redBtn, proportion=0, flag=wx.EXPAND|wx.ALL, border=5) btn_hSizer.Add(self.greenBtn, proportion=0, flag=wx.EXPAND|wx.ALL, border=5) btn_hSizer.Add(self.exitBtn, proportion=0, flag=wx.EXPAND|wx.ALL, border=5) btn_hSizer.AddStretchSpacer() colorPnlAndBtn_vSizer.Add(btn_hSizer, 0, wx.EXPAND| wx.ALL, 5) # SetSizer both sizers in the most senior control that has sizers in it. self.frmPanel.SetSizer(colorPnlAndBtn_vSizer) self.frmPanel.Layout() #------------ # Must call before any event handler is referenced. self.eventsHandler = MyEventsHandler(self) #------------ # Bind event handlers to all controls that have one. self.redBtn.Bind(wx.EVT_BUTTON, self.eventsHandler.OnRedBtn) self.greenBtn.Bind(wx.EVT_BUTTON, self.eventsHandler.OnGreenBtn) self.exitBtn.Bind(wx.EVT_BUTTON, self.eventsHandler.OnExitBtn) # Create more convenient ways to close this app. # Adding these makes a total of 5 separate ways to exit. self.frmPanel.Bind(wx.EVT_LEFT_DCLICK, self.eventsHandler.OnExitBtn) self.colourPnl.Bind(wx.EVT_LEFT_DCLICK, self.eventsHandler.OnExitBtn) #--------------------------------------------------------------------------- class MyEventsHandler() : def __init__(self, parent): self.parent = parent #----------------------------------------------------------------------- def OnRedBtn(self, event): """ ... """ self.ShowColourAndDialog(wx.RED) def OnGreenBtn(self, event): """ ... """ self.ShowColourAndDialog(wx.GREEN) def ShowColourAndDialog(self, pnlColour): """ ... """ self.parent.colourPnl.SetBackgroundColour(pnlColour) self.parent.colourPnl.Refresh() dlg = wx.MessageDialog(self.parent, 'Changed colour !', 'Successful', style = wx.ICON_INFORMATION| wx.OK) dlg.ShowModal() dlg.Destroy() def OnExitBtn(self, event): """ ... """ self.parent.Destroy() #--------------------------------------------------------------------------- class MyApp(wx.App): def OnInit(self): #------------ frame = MyFrame(None, -1, "Separate the Gui from the logic") self.SetTopWindow(frame) frame.Show(True) return True #--------------------------------------------------------------------------- def main(): app = MyApp(redirect=False) app.MainLoop() #--------------------------------------------------------------------------- if __name__ == "__main__" : main() }}} -------- = Download source = [[attachment:source.zip]] -------- = Additional Information = '''Link :''' - - - - - https://wiki.wxpython.org/TitleIndex https://docs.wxpython.org/ -------- = Thanks to = Stephen Mtangoo (sample_one.py coding), Pool (sample_two.py coding), the wxPython community... -------- = About this page = Date(d/m/y) Person (bot) Comments : 04/01/20 - Ecco (Updated page for wxPython Phoenix). -------- = Comments = - blah, blah, blah....