WxPython hiding a Horizontal BoxSizer

96 views Asked by At

I have a Horizontal boxSizer, inside which I have added 2 images (StaticBitmap).

How do I hide this sizer such that the sizers that are below it come up? Below is the code

import wx
import wx.lib
import wx.lib.scrolledpanel
import wx.lib.filebrowsebutton

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        #First retrieve the screen size of the device
        screenSize = wx.DisplaySize()
        screenWidth = screenSize[0]
        screenHeight = screenSize[1]
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        # self.SetSize((1200, 650))
        self.SetTitle("Test")
        self.Maximize(True)

        #self.SetForegroundColour(wx.WHITE)
        #self.SetBackgroundColour(wx.Colour(204, 0, 0))

        sizer_1 = wx.BoxSizer(wx.VERTICAL)

        self.nb = wx.Notebook(self, wx.ID_ANY)
        # self.nb.SetFocus()
        sizer_1.Add(self.nb, 1, wx.EXPAND, 0)


        self.nbFlash = wx.Panel(self.nb, wx.ID_ANY)
        self.nb.AddPage(self.nbFlash, "Demo")

        sizer_4 = wx.BoxSizer(wx.VERTICAL)

        label_10 = wx.StaticText(self.nbFlash, wx.ID_ANY, "Images")

        label_10.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "Arial"))
        sizer_4.Add(label_10, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)

        # sizer_4.Add((10,10), 0, 0, 0)

        sizer_29 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4.Add(sizer_29, 6, wx.EXPAND, 0)

        img1 = wx.Image("Any image path", wx.BITMAP_TYPE_ANY)
        w = img1.GetWidth()
        h = img1.GetHeight()
        w = w*0.5
        h = h*0.5
        img1 = img1.Scale(w,h)
        bitmap_2 = wx.StaticBitmap(self.nbFlash, wx.ID_ANY, wx.Bitmap(img1))
        sizer_29.Add(bitmap_2, 1, wx.EXPAND, 0)

        img2 = wx.Image("Any image path", wx.BITMAP_TYPE_ANY)
        w = img2.GetWidth()
        h = img2.GetHeight()
        w = w*0.5
        h = h*0.5
        img2 = img2.Scale(w,h)
        bitmap_3 = wx.StaticBitmap(self.nbFlash, wx.ID_ANY, wx.Bitmap(img2))
        sizer_29.Add(bitmap_3, 1, wx.EXPAND, 0)


        sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4.Add(sizer_5, 3, wx.EXPAND, 0)


        ##Bin File, COM Port
        sizer_5_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_5.Add(sizer_5_1, 1, wx.LEFT, 20)

        label_13 = wx.StaticText(self.nbFlash, wx.ID_ANY, "Upload")
        label_13.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "Arial"))
        sizer_5_1.Add(label_13, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

        sizer_5_1.Add((0,0), 1, 0, 0)

        self.fbb1 = wx.FilePickerCtrl(self.nbFlash, message="Choose an Image")
        sizer_5_1.Add(self.fbb1, 0, wx.ALIGN_CENTER_HORIZONTAL, 20)

        sizer_5_1.Add((30,30), 1, 0, 0)
        
        label_14 = wx.StaticText(self.nbFlash, wx.ID_ANY, "Add")
        label_14.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "Arial"))
        sizer_5_1.Add(label_14, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

        sizer_5_1.Add((0,0), 1, 0, 0)

        self.text = wx.TextCtrl(self.nbFlash, wx.ID_ANY, style = wx.TE_PROCESS_ENTER)

    
        sizer_5_1.Add(self.text, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

        sizer_5_1.Add((0,0), 1, wx.ALIGN_CENTER_HORIZONTAL, 0)


        self.nbFlash.SetSizer(sizer_4)
        self.SetSizer(sizer_1)

        self.Layout()

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

I am able to hide the images, but it still keeps the space of the sizers. Now instead of the image, there is blank space.

Please suggest some solution.

1

There are 1 answers

7
Rolf of Saxony On

You can either charge off down the route of getting the children and grandchildren of the widgets in sizer, dealing with them individually, or you can make use of the Sizer's ShowItems method.
I've added a Hide button, as your example, inexplicably, was missing the very method you were trying to test.

Note: example code adjusted for non maximised window

import wx
import wx.lib
import wx.lib.scrolledpanel
import wx.lib.filebrowsebutton

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        # self.SetSize((1200, 650))
        self.SetTitle("Test")

        #self.SetForegroundColour(wx.WHITE)
        #self.SetBackgroundColour(wx.Colour(204, 0, 0))

        sizer_1 = wx.BoxSizer(wx.VERTICAL)

        self.nb = wx.Notebook(self, wx.ID_ANY)
        # self.nb.SetFocus()
        sizer_1.Add(self.nb, 1, wx.EXPAND, 0)


        self.nbFlash = wx.Panel(self.nb, wx.ID_ANY)
        self.nb.AddPage(self.nbFlash, "Demo")

        sizer_4 = wx.BoxSizer(wx.VERTICAL)

        label_10 = wx.StaticText(self.nbFlash, wx.ID_ANY, "Images")

        label_10.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "Arial"))
        self.Hide_images = wx.Button(self, wx.ID_ANY, "Hide Images")
        sizer_4.Add(label_10, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)

        # sizer_4.Add((10,10), 0, 0, 0)

        self.sizer_29 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4.Add(self.sizer_29, 1, wx.EXPAND, 0)

        img1 = wx.Image("frame1.png", wx.BITMAP_TYPE_ANY)
        w = img1.GetWidth()
        h = img1.GetHeight()
        w = int(w*0.5)
        h = int(h*0.5)
        img1 = img1.Scale(w,h)
        bitmap_2 = wx.StaticBitmap(self.nbFlash, wx.ID_ANY, wx.Bitmap(img1))
        self.sizer_29.Add(bitmap_2, 1, wx.EXPAND, 0)

        img2 = wx.Image("frame2.png", wx.BITMAP_TYPE_ANY)
        w = img2.GetWidth()
        h = img2.GetHeight()
        w = int(w*0.5)
        h = int(h*0.5)
        img2 = img2.Scale(w,h)
        bitmap_3 = wx.StaticBitmap(self.nbFlash, wx.ID_ANY, wx.Bitmap(img2))
        self.sizer_29.Add(bitmap_3, 1, wx.EXPAND, 0)


        sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4.Add(sizer_5, 1, wx.EXPAND, 0)


        ##Bin File, COM Port
        sizer_5_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_5.Add(sizer_5_1, 1, wx.LEFT, 20)

        label_13 = wx.StaticText(self.nbFlash, wx.ID_ANY, "Upload")
        label_13.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "Arial"))
        sizer_5_1.Add(label_13, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

        sizer_5_1.Add((0,0), 1, 0, 0)

        self.fbb1 = wx.FilePickerCtrl(self.nbFlash, message="Choose an Image")
        sizer_5_1.Add(self.fbb1, 0, wx.ALIGN_CENTER_HORIZONTAL, 20)

        sizer_5_1.Add((30,30), 1, 0, 0)
        
        label_14 = wx.StaticText(self.nbFlash, wx.ID_ANY, "Add")
        label_14.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "Arial"))
        sizer_5_1.Add(label_14, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

        sizer_5_1.Add((0,0), 1, 0, 0)

        self.text = wx.TextCtrl(self.nbFlash, wx.ID_ANY, style = wx.TE_PROCESS_ENTER)

    
        sizer_5_1.Add(self.text, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

        sizer_5_1.Add((0,0), 1, wx.ALIGN_CENTER_HORIZONTAL, 0)


        self.nbFlash.SetSizer(sizer_4)
        self.SetSizer(sizer_1)

        self.Hide_images.Bind(wx.EVT_BUTTON, self.OnHide)

        self.Layout()
        self.Fit()
        self.images = True

    def OnHide(self, event):
        if self.images:
            self.images = False
            self.sizer_29.ShowItems(False)
            self.Hide_images.SetLabel("Show Images")
        else:
            self.images = True
            self.sizer_29.ShowItems(True)
            self.Hide_images.SetLabel("Hide Images")
        self.nbFlash.Layout()
        self.nbFlash.Fit()
        
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

enter image description hereenter image description here