Is it possible to add toggle switches like this in wxPython?
CodePudding user response:
I asked myself a similar question last year and didn't come up with a satisfactory answer.
So I wrote my own.
I did post it on wxpython-users hosted on groups-google
With the code saved as onoffbutton.py
I tend to import it with:
import onoffbutton as oob
and then use it as in the demo, something like:
self.fc_autotransparency = oob.OnOffButton(self.tab3, wx.ID_ANY)
CodePudding user response:
Here's a rough and ready example. The idea is to use two images and toggle them in the toggle_sizer. The image bitmaps are named and the toggle_click method removes the one that is currently displayed from the toggle_sizer and adds the other.
import wx
TOGGLE_SIZE = (30, 15)
class MainFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super().__init__(None, *args, **kwargs)
self.Title = 'Demonstrate toggle'
self.panel = MainPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel)
self.SetSizer(sizer)
self.Center()
self.Show()
class MainPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
sizer = wx.BoxSizer(wx.VERTICAL)
toggle_off_bitmap = self._toggle_image('toggle_off')
self.toggle_sizer = wx.BoxSizer(wx.VERTICAL)
self.toggle_sizer.Add(toggle_off_bitmap)
sizer.Add(self.toggle_sizer)
self.SetSizer(sizer)
def _toggle_image(self, bitmap_name):
toggle_bitmap = wx.Bitmap(f'{bitmap_name}.png', wx.BITMAP_TYPE_ANY)
image = wx.Bitmap.ConvertToImage(toggle_bitmap)
image = image.Scale(TOGGLE_SIZE[0], TOGGLE_SIZE[1])
bitmap_image = wx.StaticBitmap(self, wx.ID_ANY, name=bitmap_name)
bitmap_image.SetBitmap(image.ConvertToBitmap())
bitmap_image.Bind(wx.EVT_LEFT_DOWN, self.toggle_click)
return bitmap_image
def toggle_click(self, event):
toggle = event.GetEventObject().Name
if toggle == 'toggle_off':
toggle_bitmap = self._toggle_image('toggle_on')
else:
toggle_bitmap = self._toggle_image('toggle_off')
self._clear_sizer(self.toggle_sizer)
self.toggle_sizer.Add(toggle_bitmap)
def _clear_sizer(self, sizer):
for child in sizer.GetChildren():
if child.IsSizer():
if child.IsSizer():
self._clear_sizer(child.GetSizer())
else:
child.GetWindow().Destroy()
sizer.Clear()
if __name__ == '__main__':
wx_app = wx.App()
MainFrame()
wx_app.MainLoop()