多个 wx.Yield() 替代方案
我现在有一个用wxpython做的图形界面应用,它会读取一个不断增长的文本文件,并把内容显示在一个wx.TextCtrl窗口里。我需要同时运行两个这样的窗口,但显然我遇到了一个问题,就是出现了“wxYield被递归调用”的错误。请问有没有简单的方法可以替代wx.Yield,让我能够同时运行多个窗口呢?
self.running_log = wx.TextCtrl(self, -1, pos=(5, 5), size=(875,605),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
while True:
wx.Yield()
fileSize = os.path.getsize(logPath)
if fileSize > lastSize:
lines = infile.readlines()
newLines = 0
for line in lines[lastLineIndex:]:
newLines += 1
print line.rstrip()
self.running_log.AppendText(line)
2 个回答
0
wx.SafeYield() 不是为了专门解决这个问题而设计的吗?
比如,可以看看这里 点击这里查看链接
1
你可以看看 wxPython 的维基页面:LongRunningTasks。在那儿你会看到两种替代使用 wxYield 的方法:线程处理或者把你的处理放在 EVT_IDLE 处理器里。
不过既然你已经在用 wxYield,我建议你可以先试试一个解决方案,而不是马上换别的:使用一个标志来表示你是否已经在运行。如果这个标志为真,就不要让代码再次执行 wxYield。
当你调用 wx.Yield()
时,wxPython 会接管控制权,处理它需要处理的任何事件。当处理完成后,你的长时间运行的任务会在你调用 yield 之后继续进行。所以你可以把所有的处理放在一个循环里,让它在那儿转圈,只要需要就行。通过添加一个标志,你可以限制代码的入口点,只在 yield 的地方。当你的处理完成后,你通过切换标志来释放你的“锁”,这样代码的入口点就变回实际的方法调用了。
大致可以这样写:
if not running:
running = True
while True:
wx.Yield()
fileSize = os.path.getsize(self.logPath)
if fileSize > lastSize:
lines = infile.readlines()
newLines = 0
for line in lines[lastLineIndex:]:
newLines += 1
self.running_log.AppendText(line)
# When you are finished, set running to False and break
注意,检查一下 getsize
被调用的频率可能是个好主意。如果调用得太频繁,你可以通过确保经过了一段短时间来限制它,以避免过多的调用拖慢你的系统。