我正在尝试更新wxpython中的textctrl
,而长时间运行的线程正在查找某种信息。它一直运行良好,直到用户将焦点更改为另一个窗口,然后在返回到wxpython脚本时,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()
答案 0 :(得分:0)
这是一个基于Anonymous Coward评论的解决方案。我将按钮事件中的所有内容移动到一个线程中。如果有更好的方法可以告诉我。
#!/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()