2012-11-16 3 views
1

wxpython에서 textctrl을 업데이트하려고합니다. 실행 시간이 긴 스레드가 일종의 정보를 찾는 중입니다. 사용자가 포커스를 다른 창으로 변경하고 wxpython 스크립트로 돌아 가면 스레드가 완료 될 때까지 GUI가 응답하지 않습니다.GUI에서 쓰레드가 줄고있는 GUI가 있음

이 스크립트로 돌아가서 애니메이션 커서로 textctrl 업데이트를 볼 수 있습니까?

다음
#!/usr/bin/env python 
import wx 
import thread 
import Queue 
from time import sleep 

class MyFrame1 (wx.Frame): 

     def __init__(self, parent): 
       wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(500,300), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 

       self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 

       bSizer1 = wx.BoxSizer(wx.VERTICAL) 

       self.m_panel1 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
       bSizer2 = wx.BoxSizer(wx.VERTICAL) 

       self.m_button1 = wx.Button(self.m_panel1, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0) 
       bSizer2.Add(self.m_button1, 0, wx.ALL, 5) 

       self.m_panel1.SetSizer(bSizer2) 
       self.m_panel1.Layout() 
       bSizer2.Fit(self.m_panel1) 
       bSizer1.Add(self.m_panel1, 1, wx.EXPAND |wx.ALL, 5) 

       self.m_panel2 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
       bSizer3 = wx.BoxSizer(wx.VERTICAL) 

       self.m_textCtrl1 = wx.TextCtrl(self.m_panel2, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE) 
       bSizer3.Add(self.m_textCtrl1, 1, wx.ALL|wx.EXPAND, 5) 

       self.m_panel2.SetSizer(bSizer3) 
       self.m_panel2.Layout() 
       bSizer3.Fit(self.m_panel2) 
       bSizer1.Add(self.m_panel2, 1, wx.EXPAND |wx.ALL, 5) 

       self.SetSizer(bSizer1) 
       self.Layout() 

       self.Centre(wx.BOTH) 

       # Connect Events 
       self.m_button1.Bind(wx.EVT_BUTTON, self.do_something) 

     def __del__(self): 
       pass 


     # Virtual event handlers, overide them in your derived class 
     def do_something(self, event): 
       event.Skip() 



class MyFrame(MyFrame1): 
    def __init__(self, parent): 
     MyFrame1.__init__(self, parent) 

    def do_something(self, event): 
     self.Result = Queue.Queue() 
     thread.start_new_thread(self.do_loop,()) 
     self.m_textCtrl1.AppendText("searching for something... ") 
     self.found= 0 
     for character in self.cursor(): 
      self.m_textCtrl1.AppendText(character) 
      self.Update() 
      sleep(0.1) 
      self.m_textCtrl1.Undo() 
      if (self.found == 1): 
       self.m_textCtrl1.AppendText('\n') 
       break 
     num = self.Result.get() 
     print num 

    def cursor(self): 
     characters='.oOo' 
     i = 0 
     while 1: 
      yield characters[i] 
      i = (i + 1) % len(characters) 

    def do_loop(self): 
     x = 0 
     while (x < 20007): 
      print x 
      x = x + 1 
      if x == 20000: 
       self.Result.put(x) 
       self.found = 1 
       break 

class threadtest(wx.App): 
    def OnInit(self): 
     self.m_frame = MyFrame(None) 
     self.m_frame.Show() 
     self.SetTopWindow(self.m_frame) 
     return True 

app = threadtest(0) 
app.MainLoop() 
+1

MyFrame.do_something()의 루프가 이벤트 루프를 차단하고 있습니다. –

+0

아, 그래, 애니메이션 커서를 다른 스레드에 넣으면 단추 이벤트를 차단 해제해야합니다. 나는 이것을 가지고 놀 것이다. – GolfDope

답변

0

익명 겁쟁이의 의견을 기반으로 솔루션입니다 :

여기에 코드입니다. 단추 이벤트에서 스레드로 모든 것을 옮겼습니다. 이 작업을 수행하는 더 좋은 방법이 있는지 알려주십시오.

#!/usr/bin/env python 
import wx 
import thread 
import Queue 
from time import sleep 

class MyFrame1 (wx.Frame): 

     def __init__(self, parent): 
       wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(500,300), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 

       self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 

       bSizer1 = wx.BoxSizer(wx.VERTICAL) 

       self.m_panel1 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
       bSizer2 = wx.BoxSizer(wx.VERTICAL) 

       self.m_button1 = wx.Button(self.m_panel1, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0) 
       bSizer2.Add(self.m_button1, 0, wx.ALL, 5) 

       self.m_panel1.SetSizer(bSizer2) 
       self.m_panel1.Layout() 
       bSizer2.Fit(self.m_panel1) 
       bSizer1.Add(self.m_panel1, 1, wx.EXPAND |wx.ALL, 5) 

       self.m_panel2 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
       bSizer3 = wx.BoxSizer(wx.VERTICAL) 

       self.m_textCtrl1 = wx.TextCtrl(self.m_panel2, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE) 
       bSizer3.Add(self.m_textCtrl1, 1, wx.ALL|wx.EXPAND, 5) 

       self.m_panel2.SetSizer(bSizer3) 
       self.m_panel2.Layout() 
       bSizer3.Fit(self.m_panel2) 
       bSizer1.Add(self.m_panel2, 1, wx.EXPAND |wx.ALL, 5) 

       self.SetSizer(bSizer1) 
       self.Layout() 

       self.Centre(wx.BOTH) 

       # Connect Events 
       self.m_button1.Bind(wx.EVT_BUTTON, self.do_something) 

     def __del__(self): 
       pass 


     # Virtual event handlers, overide them in your derived class 
     def do_something(self, event): 
       event.Skip() 



class MyFrame(MyFrame1): 
    def __init__(self, parent): 
     MyFrame1.__init__(self, parent) 

    def do_something(self, event): 
     thread.start_new_thread(self.do_something_thread,()) 

    def do_something_thread(self): 
     self.Result = Queue.Queue() 
     thread.start_new_thread(self.do_loop,()) 
     self.m_textCtrl1.AppendText("searching for something... ") 
     self.found= 0 
     for character in self.cursor(): 
      self.m_textCtrl1.AppendText(character) 
      self.Update() 
      sleep(0.1) 
      self.m_textCtrl1.Undo() 
      if (self.found == 1): 
       self.m_textCtrl1.AppendText('\n') 
       break 
     num = self.Result.get() 
     print num 

    def cursor(self): 
     characters='.oOo' 
     i = 0 
     while 1: 
      yield characters[i] 
      i = (i + 1) % len(characters) 

    def do_loop(self): 
     x = 0 
     while (x < 20007): 
      print x 
      x = x + 1 
      if x == 20000: 
       self.Result.put(x) 
       self.found = 1 
       break 

class threadtest(wx.App): 
    def OnInit(self): 
     self.m_frame = MyFrame(None) 
     self.m_frame.Show() 
     self.SetTopWindow(self.m_frame) 
     return True 

app = threadtest(0) 
app.MainLoop() 
관련 문제