2017-05-04 1 views
0

Ich bin neu mit wxPython und ich möchte eine While-Schleife nur ausführen, wenn bestimmte Panel (Panel1) angezeigt wird und stoppen, wenn das Panel ausgeblendet wird.Wie führe ich eine while-Schleife aus, wenn wx.panel angezeigt wird?

Ich interessiere mich für die Schleife, weil ich einen Wert der Bezeichnung ändern möchte, die in der Panel1 ist.

Ich habe versucht, buchstäblich, um den Code while True: ... gestellt, aber hat nicht funktioniert,

Irgendwelche Vorschläge?

+2

ist die beste Wette, einen Thread zu starten und tun, was Sie wollen in. Überprüfen Sie die wxPython-Demo über das MT. – Igor

+2

Je nachdem, was Sie tatsächlich benötigen, reicht ein Timer gerade aus. Suchen Sie nicht blockierende GUI oder LongRunningTasks auf wiki.wxpython.org. –

Antwort

0

Wie die anderen bereits erwähnt haben, können Sie einen Thread oder einen wx.Timer verwenden, um das zu erreichen, was Sie suchen. Ich nahm etwas Code von meinem alten Panel tutorial und änderte es, um zu zeigen, wie man den Timer-Ansatz verwendet.

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() 

Ich persönlich denke, mit einem Gewinde für diese Overkill ist: Alles, was Sie tun müssen, ist den folgenden Code und schalten die Platten über das Menü ausgeführt werden. Es hat jedoch Spaß gemacht, den Code oben zu ändern, um stattdessen einen Thread zu verwenden. Also hier ist die Version auch:

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() 

Beachten Sie, dass die enge Veranstaltung über EVT_CLOSE um sicherzustellen, dass der Thread gestoppt fangen wollen, wenn Sie Ihre Anwendung beenden oder Sie haben Ihre Anwendung hängen oder sich schlecht benehmen.

+0

Danke! Es hat gut funktioniert. Ich habe total Threads vergessen. Danke noch einmal :) –

Verwandte Themen