How to separate Gui and logic (Phoenix)
Keywords : Gui, Frame, Events handler, Widget.
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
ICON file : wxwin.ico
1 # sample_one.py
2
3 import wx
4
5 # class MyFrame
6 # class MyEvents
7 # class MyApp
8
9 #---------------------------------------------------------------------------
10
11 class MyFrame(wx.Frame):
12 def __init__(self, parent, id, title):
13 wx.Frame.__init__(self, parent, id, title)
14
15 self.SetIcon(wx.Icon("wxwin.ico"))
16
17 #------------
18
19 self.functions = MyEvents(self)
20 self.panel = wx.Panel(self, -1)
21
22 #------------
23
24 # Add two buttons and text control.
25 self.text = wx.TextCtrl(self.panel, -1)
26 self.text.SetLabel("Hello world !")
27 self.text.SetForegroundColour("white")
28 self.text.SetBackgroundColour(wx.BLACK)
29
30 self.button1 = wx.Button(self.panel, -1, "Red Colour")
31 self.button2 = wx.Button(self.panel, -1, "Green Colour")
32
33 #------------
34
35 # Bind events to widgets.
36 self.Bind(wx.EVT_BUTTON, self.functions.OnRed, id = self.button1.GetId())
37 self.Bind(wx.EVT_BUTTON, self.functions.OnGreen, id = self.button2.GetId())
38
39 #------------
40
41 # Add them to sizer [define it first to prevent python
42 # automatic detector to find you red handed].
43 main = wx.BoxSizer(wx.VERTICAL)
44 main.Add(self.text, 1, wx.EXPAND|wx.ALL, 1)
45
46 #------------
47
48 # Add buttons in separate sizer.
49 sub_main = wx.BoxSizer(wx.HORIZONTAL)
50 sub_main.Add(self.button1, 0, wx.EXPAND| wx.ALL, 5)
51 sub_main.Add(self.button2, 0, wx.EXPAND| wx.ALL, 5)
52 main.Add(sub_main, 0, wx.EXPAND| wx.ALL, 5)
53
54 #------------
55
56 # Set sizers to Frame through panel.
57 self.panel.SetSizer(main)
58 self.panel.Layout()
59
60 #---------------------------------------------------------------------------
61
62 class MyEvents():
63 def __init__(self, parent):
64
65 self.gui = parent
66
67 #-----------------------------------------------------------------------
68
69 def OnRed(self, evt):
70 self.gui.text.SetBackgroundColour("Red")
71
72 dlg = wx.MessageDialog(self.gui,
73 "Changed colour ! Click on the window to see !",
74 "Successful",
75 style = wx.ICON_INFORMATION| wx.OK)
76 dlg.ShowModal()
77 if dlg.ShowModal == wx.ID_OK:
78 dlg.Destroy()
79
80
81 def OnGreen(self, evt):
82 self.gui.text.SetBackgroundColour(wx.GREEN)
83
84 dlg = wx.MessageDialog(self.gui,
85 "Changed colour ! Click on the window to see !",
86 "Successful",
87 style = wx.ICON_INFORMATION| wx.OK)
88 dlg.ShowModal()
89 if dlg.ShowModal == wx.ID_OK:
90 dlg.Destroy()
91
92 #---------------------------------------------------------------------------
93
94 class MyApp(wx.App):
95 def OnInit(self):
96
97 #------------
98
99 frame = MyFrame(None, -1,
100 "Classes and interactions")
101 self.SetTopWindow(frame)
102 frame.Show(True)
103
104 return True
105
106 #---------------------------------------------------------------------------
107
108 def main():
109 app = MyApp(redirect=False)
110 app.MainLoop()
111
112 #---------------------------------------------------------------------------
113
114 if __name__ == "__main__" :
115 main()
Second example
ICON file : wxwin.ico
1 # sample_two.py
2
3 import wx
4
5 # class MyFrame
6 # class MyEventsHandler
7 # class MyApp
8
9 #---------------------------------------------------------------------------
10
11 class MyFrame(wx.Frame):
12 def __init__(self, parent, id, title):
13 wx.Frame.__init__(self, parent, -1, title=title)
14
15 self.SetIcon(wx.Icon("wxwin.ico"))
16
17 #------------
18
19 self.frmPanel = wx.Panel(self)
20 self.frmPanel.BackgroundColour = (200, 240, 250) # light blue
21
22 #------------
23
24 # Add another panel and some buttons
25 self.colourPnl = wx.Panel(self.frmPanel)
26 self.colourPnl.SetBackgroundColour(wx.Colour('GREY'))
27
28 #------------
29
30 self.redBtn = wx.Button(self.frmPanel, label='Red')
31 self.greenBtn = wx.Button(self.frmPanel, label='Green')
32 self.exitBtn = wx.Button(self.frmPanel, label='Exit')
33
34 #------------
35
36 # Add them to sizer.
37 colorPnlAndBtn_vSizer = wx.BoxSizer(wx.VERTICAL)
38 colorPnlAndBtn_vSizer.Add(self.colourPnl, 1, wx.EXPAND|wx.ALL, 1)
39
40 # Add buttons in their own sizer
41 btn_hSizer = wx.BoxSizer(wx.HORIZONTAL)
42 btn_hSizer.AddStretchSpacer()
43 btn_hSizer.Add(self.redBtn, proportion=0, flag=wx.EXPAND|wx.ALL, border=5)
44 btn_hSizer.Add(self.greenBtn, proportion=0, flag=wx.EXPAND|wx.ALL, border=5)
45 btn_hSizer.Add(self.exitBtn, proportion=0, flag=wx.EXPAND|wx.ALL, border=5)
46 btn_hSizer.AddStretchSpacer()
47
48 colorPnlAndBtn_vSizer.Add(btn_hSizer, 0, wx.EXPAND| wx.ALL, 5)
49
50 # SetSizer both sizers in the most senior control that has sizers in it.
51 self.frmPanel.SetSizer(colorPnlAndBtn_vSizer)
52 self.frmPanel.Layout()
53
54 #------------
55
56 # Must call before any event handler is referenced.
57 self.eventsHandler = MyEventsHandler(self)
58
59 #------------
60
61 # Bind event handlers to all controls that have one.
62 self.redBtn.Bind(wx.EVT_BUTTON, self.eventsHandler.OnRedBtn)
63 self.greenBtn.Bind(wx.EVT_BUTTON, self.eventsHandler.OnGreenBtn)
64 self.exitBtn.Bind(wx.EVT_BUTTON, self.eventsHandler.OnExitBtn)
65
66 # Create more convenient ways to close this app.
67 # Adding these makes a total of 5 separate ways to exit.
68 self.frmPanel.Bind(wx.EVT_LEFT_DCLICK, self.eventsHandler.OnExitBtn)
69 self.colourPnl.Bind(wx.EVT_LEFT_DCLICK, self.eventsHandler.OnExitBtn)
70
71 #---------------------------------------------------------------------------
72
73 class MyEventsHandler() :
74 def __init__(self, parent):
75
76 self.parent = parent
77
78 #-----------------------------------------------------------------------
79
80 def OnRedBtn(self, event):
81 """
82 ...
83 """
84
85 self.ShowColourAndDialog(wx.RED)
86
87
88 def OnGreenBtn(self, event):
89 """
90 ...
91 """
92
93 self.ShowColourAndDialog(wx.GREEN)
94
95
96 def ShowColourAndDialog(self, pnlColour):
97 """
98 ...
99 """
100
101 self.parent.colourPnl.SetBackgroundColour(pnlColour)
102 self.parent.colourPnl.Refresh()
103 dlg = wx.MessageDialog(self.parent, 'Changed colour !', 'Successful',
104 style = wx.ICON_INFORMATION| wx.OK)
105 dlg.ShowModal()
106 dlg.Destroy()
107
108
109 def OnExitBtn(self, event):
110 """
111 ...
112 """
113
114 self.parent.Destroy()
115
116 #---------------------------------------------------------------------------
117
118 class MyApp(wx.App):
119 def OnInit(self):
120
121 #------------
122
123 frame = MyFrame(None, -1,
124 "Separate the Gui from the logic")
125 self.SetTopWindow(frame)
126 frame.Show(True)
127
128 return True
129
130 #---------------------------------------------------------------------------
131
132 def main():
133 app = MyApp(redirect=False)
134 app.MainLoop()
135
136 #---------------------------------------------------------------------------
137
138 if __name__ == "__main__" :
139 main()
Download source
Additional Information
Link :
- - - - -
https://wiki.wxpython.org/TitleIndex
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....