2017-05-04 1 views
0

私はwxPythonを使って新しく、特定のパネル(Panel1)が表示されているときにwhileループを実行し、パネルが非表示になったときに停止します。wx.panelが表示されているときにwhileループを実行するには?

Panel1にあるラベルの値を変更したいのでループに興味があります。

私は、文字通りコードwhile True: ...を入れてみましたが、うまくいきませんでした

任意の提案は?

+2

あなたは最善の策は、スレッドを開始し、あなたが欲しいものをすることです。 MTについてのwxPythonのデモを確認してください。 – Igor

+2

実際に必要なものによっては、タイマーで十分です。 wiki.wxpython.orgでノンブロッキングGUIまたはLongRunningTasksを参照してください。 –

答えて

0

他にも言及したように、スレッドまたはwx.Timerを使用して、探しているものを達成できます。私は古いパネルのスイッチtutorialからいくつかのコードを取得し、それを修正してタイマー手法の使い方を示しました。あなたがしなければならないのは、次のコードを実行し、メニューからパネルを切り替えている:これはやり過ぎであるため

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

個人的に、私はスレッドを使用して考えてみてください。しかし、上記のコードを変更してスレッドを使用するのは面白いことでした。アプリケーションを終了するか、あなたのアプリケーションがハングアップしたり不正な動作を持っていることと、スレッドが停止していることを確認するEVT_CLOSE経由クローズイベントをキャッチしたいと思うでしょう

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

注:だから、ここでもそのバージョンです。

+0

ありがとう!それはうまくいった。私はスレッドを完全に忘れてしまった。再度、感謝します :) –

関連する問題