Reputation: 303
I have a wx.Frame
. I need to change the content from time to time.
I have a timer and every few seconds I check the state, and if the state has been changed, I need to change the content of the frame.
In order to do this, I created a panel in the frame called panel.Reparent(None)
, and created a panel with new content, but the frame is not updated with the newly created panel. I tried with destroy (panel.Destroy()
) but this didn't work.
What is the recommended way to change frame content (not only data, I need to add and remove UI components)?
class TestFrame(wx.Frame): def init(self): wx.Frame.init(self, None, title="Double Buffered Drawing") self.counter = 0 self.panel = wx.Panel(self, -1) wx.CheckBox(self.panel, -1, "Alpha", (35, 40), (150, 20))
# Create a timer to update the data values
self.Bind(wx.EVT_TIMER, self.OnTimeout)
self.timer = wx.Timer(self)
self.timer.Start(5000)
def OnTimeout(self, evt):
p = self.panel
self.counter = self.counter + 1
try:
p.Reparent(None)
except e:
print 'B'
if self.counter % 2 == 0:
self.panel = wx.Panel(self, -1)
wx.CheckBox(self.panel, -1, "Alpha", (35, 40), (150, 20))
self.Show() #Tried also self.Layout self.Refresh self.Update
Upvotes: 0
Views: 2742
Reputation: 33111
When adding or removing widgets during run time, you almost always have to call Layout() after the removal or addition of a widget. Usually calling Layout on the parent sizer will do the trick, but sometimes you have to call it on the frame object. You can see one example here where I just hid one panel and showed another.
I also wrote another tutorial on actually removing or adding widgets dynamically. That might help you too.
EDIT (6-26-12): Since the OP seems to require an example, I wrote a self-destructing panel:
import wx
########################################################################
class PanelOne(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
self.countdown = wx.StaticText(self, label="This panel will self-destruct in 10 seconds")
########################################################################
class PanelTwo(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
txt = wx.StaticText(self, label="Panel Two")
########################################################################
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Panel Smacker")
self.panelOne = PanelOne(self)
self.time2die = 10
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update, self.timer)
self.timer.Start(1000)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.panelOne, 1, wx.EXPAND)
self.SetSizer(self.sizer)
#----------------------------------------------------------------------
def update(self, event):
""""""
if self.time2die < 0:
self.panelOne.Destroy()
self.panelTwo = PanelTwo(self)
self.sizer.Add(self.panelTwo, 1, wx.EXPAND)
self.Layout()
self.timer.Stop()
else:
msg = "This panel will self-destruct in %s seconds" % self.time2die
self.panelOne.countdown.SetLabel(msg)
self.time2die -= 1
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
frame.Show()
app.MainLoop()
Upvotes: 1