Hide/Show Gauge not working correctly

Here is a simple wxPython app:

import wx

app = wx.App(False)
frame = wx.Frame(None, title='Hide/Show bug', size=(400,600))
framesizer = wx.BoxSizer(); frame.SetSizer(framesizer)

panel = wx.Panel(frame)
panelsizer = wx.BoxSizer(orient=wx.VERTICAL)
panel.SetSizer(panelsizer)
framesizer.Add(panel, 1, wx.EXPAND)

heading = wx.StaticText(panel, label="heading")
panelsizer.Add(heading, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, border=12)

button = wx.Button(panel, label="Show the gauge")
progress = wx.Gauge(panel, style=wx.GA_HORIZONTAL | wx.GA_SMOOTH | wx.GA_PROGRESS)
panelsizer.Add(button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, border=12)
panelsizer.Add(progress, 0, wx.EXPAND | wx.ALL, border=12)
button.Bind(wx.EVT_BUTTON, lambda e, progress=progress: progress.Show())
#progress.Hide()

frame.Show(); app.MainLoop()

If you run this (on Linux but Mac seems to have the same issue), you get the same sort of correct view, with a simple panel with a button and a Gauge:

image

but! if I add back in the progress.Hide() line, which is currently commented out, and then press the button to show the Gauge at runtime, it looks like this:

image

that is: the Gauge now appears unaligned at the top of the window, rather than appearing in the correct place.

What am I doing wrong here? Is it not OK to hide and show elements in a sizer? Should I be doing something else instead to hide the progress bar and then make it appear on command?

I think you need to call the Frame’s Layout() method after showing the gauge. I couldn’t figure out how to add that to the lambda expression, so I hacked your code into a more conventional format:

import wx

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        framesizer = wx.BoxSizer()

        panel = wx.Panel(self)
        panelsizer = wx.BoxSizer(orient=wx.VERTICAL)
        panel.SetSizer(panelsizer)
        framesizer.Add(panel, 1, wx.EXPAND)

        heading = wx.StaticText(panel, label="heading")
        panelsizer.Add(heading, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, border=12)

        button = wx.Button(panel, label="Show the gauge")
        self.progress = wx.Gauge(panel, style=wx.GA_HORIZONTAL | wx.GA_SMOOTH | wx.GA_PROGRESS)
        panelsizer.Add(button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, border=12)
        panelsizer.Add(self.progress, 0, wx.EXPAND | wx.ALL, border=12)
        button.Bind(wx.EVT_BUTTON, self.OnShow)
        self.progress.Hide()

        self.SetSizer(framesizer)
        self.Layout()

    def OnShow(self, event):
        self.progress.Show()
        self.Layout()

app = wx.App(False)
frame = MyFrame(None, title='Hide/Show bug', size=(400,600))
frame.Show()
app.MainLoop()

This works OK on Python 3.10.6 + wxPython 4.2.0 gtk3 (phoenix) wxWidgets 3.2.0 + Linux Mint 21.1

1 Like

aha! Yes, that fixes it; thank you!