Comme les autres l'ont mentionné, vous pouvez utiliser un thread ou un wx.Timer
pour accomplir ce que vous cherchez. J'ai attrapé du code de mon ancien panneau en changeant tutorial et l'ai modifié pour montrer comment utiliser l'approche du minuteur. Tout ce que vous devez faire est de lancer le code suivant et commuter les panneaux via le menu:
import wx
import wx.grid as gridlib
########################################################################
class PanelOne(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
grid = gridlib.Grid(self)
grid.CreateGrid(25,12)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(grid, 0, wx.EXPAND)
self.SetSizer(sizer)
########################################################################
class PanelTwo(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
self.count = 0
self.lbl = wx.StaticText(self,
label='Counter: {}'.format(self.count))
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update, self.timer)
#----------------------------------------------------------------------
def start_timer(self):
self.timer.Start(1000)
#----------------------------------------------------------------------
def stop_timer(self):
self.timer.Stop()
#----------------------------------------------------------------------
def update(self, event):
self.count += 1
self.lbl.SetLabel('Counter: {}'.format(self.count))
########################################################################
class MyForm(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
"Panel Switcher Tutorial")
self.panel_one = PanelOne(self)
self.panel_two = PanelTwo(self)
self.panel_two.Hide()
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.panel_one, 1, wx.EXPAND)
self.sizer.Add(self.panel_two, 1, wx.EXPAND)
self.SetSizer(self.sizer)
menubar = wx.MenuBar()
fileMenu = wx.Menu()
switch_panels_menu_item = fileMenu.Append(wx.ID_ANY,
"Switch Panels",
"Some text")
self.Bind(wx.EVT_MENU, self.onSwitchPanels,
switch_panels_menu_item)
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
#----------------------------------------------------------------------
def onSwitchPanels(self, event):
""""""
if self.panel_one.IsShown():
self.SetTitle("Panel Two Showing")
self.panel_one.Hide()
self.panel_two.Show()
self.panel_two.start_timer()
else:
self.SetTitle("Panel One Showing")
self.panel_one.Show()
self.panel_two.stop_timer()
self.panel_two.Hide()
self.Layout()
# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop()
Personnellement, je pense que l'aide d'un fil pour cela est exagéré. Cependant, il était amusant de modifier le code ci-dessus pour utiliser un thread à la place. Voici donc cette version aussi:
import time
import wx
import wx.grid as gridlib
from threading import Thread
########################################################################
class TestThread(Thread):
"""Test Worker Thread Class."""
#----------------------------------------------------------------------
def __init__(self, panel):
"""Init Worker Thread Class."""
Thread.__init__(self)
self.panel = panel
self.sentinel = True
self.start() # start the thread
#----------------------------------------------------------------------
def run(self):
"""Run Worker Thread."""
# This is the code executing in the new thread.
while self.sentinel:
time.sleep(1)
wx.CallAfter(self.panel.update)
print 'Thread finished!'
########################################################################
class PanelOne(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
grid = gridlib.Grid(self)
grid.CreateGrid(25,12)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(grid, 0, wx.EXPAND)
self.SetSizer(sizer)
########################################################################
class PanelTwo(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
self.count = 0
self.lbl = wx.StaticText(self,
label='Counter: {}'.format(self.count))
self.thread = None
#----------------------------------------------------------------------
def start_timer(self):
self.thread = TestThread(self)
#----------------------------------------------------------------------
def stop_timer(self):
self.thread.sentinel = False
#----------------------------------------------------------------------
def update(self):
self.count += 1
self.lbl.SetLabel('Counter: {}'.format(self.count))
########################################################################
class MyForm(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
"Panel Switcher Tutorial")
self.panel_one = PanelOne(self)
self.panel_two = PanelTwo(self)
self.panel_two.Hide()
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.panel_one, 1, wx.EXPAND)
self.sizer.Add(self.panel_two, 1, wx.EXPAND)
self.SetSizer(self.sizer)
menubar = wx.MenuBar()
fileMenu = wx.Menu()
switch_panels_menu_item = fileMenu.Append(wx.ID_ANY,
"Switch Panels",
"Some text")
self.Bind(wx.EVT_MENU, self.onSwitchPanels,
switch_panels_menu_item)
self.Bind(wx.EVT_CLOSE, self.on_close)
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
#----------------------------------------------------------------------
def onSwitchPanels(self, event):
""""""
if self.panel_one.IsShown():
self.SetTitle("Panel Two Showing")
self.panel_one.Hide()
self.panel_two.Show()
self.panel_two.start_timer()
else:
self.SetTitle("Panel One Showing")
self.panel_one.Show()
self.panel_two.stop_timer()
self.panel_two.Hide()
self.Layout()
#----------------------------------------------------------------------
def on_close(self, event):
self.panel_two.stop_timer()
self.panel_two.thread.join()
self.Destroy()
# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop()
Notez que vous voulez attraper l'événement près par EVT_CLOSE
pour vous assurer que le fil est arrêté lorsque vous quittez votre application ou vous pouvez avoir votre application ou se conduisent mal accrocher.
votre meilleur pari sera de commencer un fil et faire ce que vous voulez à l'intérieur. Vérifiez la démo wxPython sur le MT. – Igor
En fonction de ce dont vous avez réellement besoin, une minuterie peut être juste suffisante. Recherchez l'interface graphique non bloquante ou LongRunningTasks sur wiki.wxpython.org. –