In this Python GUI Development article we want to learn about Advance GUI Development with wxPython and Python, Graphical User Interfaces (GUIs) are powerful way of creating interactive applications and wxPython is one of the most powerful GUI library available for Python developers. it provides complete set of widgets and controls, powerful event driven programming model and native look and feel on Windows, macOS and Linux. in this article we want to talk about advanced GUI development with wxPython, and we want to cover different topics such as custom controls, data binding and layout management.
Advance GUI Development with wxPython and Python
First of all we need to install wxPython
1 |
pip install wxPython |
So now let’s create our first Python GUI Application with wxPython, we need to create new application. this is done by creating new instance of the wx.App class which represents the entire application. we also need to create top level window which is represented by the wx.Frame class. this is the code.
Run the code and this will be the result
wxPython provides different controls that can be used to build complex user interfaces. these controls are created by instantiating classes that represent each control. for example wx.Button class represents a button control and the wx.StaticText class represents static text label. this is an example of how to use these controls:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import wx class MyFrame(wx.Frame): def __init__(self): super().__init__(None, title='Geekscoders.com') panel = wx.Panel(self) self.button = wx.Button(panel, label='Click me') self.text = wx.StaticText(panel, label='Welcome to geekscoders.com') sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.button, 0, wx.ALL, 10) sizer.Add(self.text, 0, wx.ALL, 10) panel.SetSizer(sizer) self.Show() if __name__ == '__main__': app = wx.App() frame = MyFrame() app.MainLoop() |
This code creates new wx.Panel object and adds a button and a static text label to it. after that we creates wx.BoxSizer object and add the button and text controls to it. and finally we set the sizer as the panel’s layout manager using the SetSizer method.
This will be the result
There may be situations where builtin controls in wxPython do not meet your specific requirements. in such cases you can create custom controls using a combination of wxPython builtin controls and your own custom code, creating custom control in wxPython involves subclassing an existing control and adding your own functionality. for example you could subclass wx.TextCtrl to create custom control that automatically formats input to specific pattern such as a phone number.
This is an example of creating custom control by subclassing wx.Control:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import wx class MyControl(wx.Control): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.NO_BORDER): wx.Control.__init__(self, parent, id, pos, size, style) self.Bind(wx.EVT_PAINT, self.OnPaint) def OnPaint(self, event): dc = wx.PaintDC(self) dc.SetPen(wx.Pen(wx.BLACK)) dc.SetBrush(wx.Brush(wx.WHITE)) dc.DrawRectangle(self.GetClientRect()) dc.DrawText("My Control", 0, 0) |
Using custom control is similar to using any other control in wxPython. you create an instance of the control and add it to parent window using sizer or by setting its position and size directly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import wx class MyControl(wx.Control): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.NO_BORDER): wx.Control.__init__(self, parent, id, pos, size, style) self.Bind(wx.EVT_PAINT, self.OnPaint) def OnPaint(self, event): dc = wx.PaintDC(self) dc.SetPen(wx.Pen(wx.BLACK)) dc.SetBrush(wx.Brush(wx.WHITE)) dc.DrawRectangle(self.GetClientRect()) dc.DrawText("My Control", 0, 0) class MyFrame(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, title=title) self.control = MyControl(self, size=(100, 100)) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.control, 0, wx.CENTER) self.SetSizer(sizer) self.Fit() if __name__ == '__main__': app = wx.App() frame = MyFrame(None, "Custom Control") frame.Show(True) app.MainLoop() |
Run the code and this will be the result
This is an advance example of creating calculator with Python and wxPython
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
import wx class Calculator(wx.Frame): def __init__(self, parent, title): super(Calculator, self).__init__(parent, title=title, size=(250, 250)) # create the main panel self.panel = wx.Panel(self) # create the calculator display self.display = wx.TextCtrl(self.panel, style=wx.TE_RIGHT) # create the calculator buttons self.buttons = [ '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '=', '+' ] # create a grid sizer for the buttons gs = wx.GridSizer(4, 4, 5, 5) # add the buttons to the grid sizer for label in self.buttons: button = wx.Button(self.panel, label=label) gs.Add(button, 0, wx.EXPAND) self.Bind(wx.EVT_BUTTON, self.on_button_click, button) # create a vertical box sizer for the layout vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(self.display, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 4) vbox.Add(gs, 1, wx.EXPAND) # set the main panel sizer self.panel.SetSizer(vbox) # show the calculator self.Show() def on_button_click(self, event): button = event.GetEventObject() label = button.GetLabel() value = self.display.GetValue() if label == '=': try: result = str(eval(value)) except: result = 'Error' self.display.SetValue(result) elif label == 'C': self.display.SetValue('') else: self.display.SetValue(value + label) if __name__ == '__main__': app = wx.App() Calculator(None, title='Calculator') app.MainLoop() |
This code creates a Calculator class that extends wx.Frame and defines calculator UI and functionality. __init__ method creates main panel, calculator display and calculator buttons. it also creates grid sizer for the buttons and vertical box sizer for the layout. on_button_click method is called when a button is clicked and performs the appropriate action based on the button’s label.
This will be the calculator result