在wxPython和跨平台兼容性方面,我似乎只有麻烦:(
我有以下功能。当用户单击一个按钮时调用它,它执行一些可能需要一段时间的工作,在此期间状态栏中会显示一个进度表。在
def Go(self, event):
progress = 0
self.statbar.setprogress(progress)
self.Update()
# ...
for i in range(1, numwords + 1):
progress = int(((float(i) / float(numwords)) * 100) - 1)
self.wrdlst.append(words.next())
self.statbar.setprogress(progress)
self.Update()
self.wrdlst.Refresh()
# ...
progress = 100
self.PushStatusText(app.l10n['msc_genwords'] % numwords)
self.statbar.setprogress(progress)
显然,在Linux下需要调用self.Update()
,否则在函数退出之前,规范不会更新,这使得它有点毫无意义。这些调用在Windows下似乎没有效果(至少是win7)。在
整个过程在Linux下运行得很好(通过调用Update()),但是在windows7上,这个指标似乎在函数退出之前的20-25%左右停止。因此,它会按它应该的方式移动,直到达到~25%,然后仪表会无缘无故地停止移动,但功能继续良好,并以适当的输出退出。在
在我试图找出问题的过程中,我尝试在更新循环内部的仪表之前插入一条print progress
行,认为progress
的值可能不是我认为的那样。令我大吃一惊的是,这个量表现在正常工作,但是当我把它取下的时候,它就停止工作了。我也可以用调用time.sleep(0.001)
来代替打印,但是即使在这么短的睡眠时间内,这个过程仍然几乎停止,如果我再降低它,问题就会再次出现,因此它几乎没有什么帮助。在
我不知道发生了什么,也不知道如何解决它,但我想不知怎么的,Windows下的东西移动得太快了,以至于progress
在一段时间后无法正确更新,而只是保持在一个固定值(~25)。我不知道为什么会这样,但是,这对我来说毫无意义。当然,print
和{
如果你需要更多的信息或代码,请告诉我。在
编辑:好的,这里有一个正在工作的应用程序(至少对我来说)有问题。时间还很长,但我试着删掉所有与手头问题无关的东西。在
它可以在Linux上运行,就像完整的应用程序一样。在Windows下,它要么失败要么工作,这取决于Go函数中numwords
的值。如果我把它的值增加到1000000(一百万),问题就消失了。我怀疑这可能取决于系统,所以如果它适合您,请尝试调整numwords
的值。这也可能是因为我更改了它,使其Append()
是一个静态文本,而不是像在原始代码中那样调用生成器。在
不过,对于我来说,当前值为numwords
(100000),它在Windows上确实失败了。在
编辑2:下面是代码的更简单版本。我想我不能把它弄小很多。我还是有问题。我可以在IDLE中运行它,也可以直接在Windows中双击.py文件来运行,无论哪种方式都是一样的。在
我尝试使用numwords
的各种值。问题似乎并没有像我第一次说的那样消失,相反,当我增加numwords
时,量规在print
被调用之前会越来越远。以目前的价值1.000.000,这个较短的版本达到大约50%。在上面的较长版本中,值1.000.000达到大约90%,值100.000达到大约25%,而值10.000只达到10%左右。在
在下面的版本中,一旦调用print
,进程将继续并达到99%,即使此时循环必须已经结束。在原始版本中,对self.wrdlst.Refresh()
的调用(当numwords为高值时需要几秒钟)一定导致了仪表暂停。所以我认为会发生这样的情况:在回路中,仪表只到达某一点,当回路退出时,功能继续工作,而仪表保持静止;当功能退出时,仪表继续工作,直到达到99%。因为打印语句不需要太多时间,下面的版本使它看起来像就像压力计从0%平稳地移动到99%,但是print
则相反。在
import wx
class MainFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super(MainFrame, self).__init__(*args, **kwargs)
self.panel = wx.Panel(self)
self.gobtn = wx.Button(self.panel, label="Go")
self.prog = wx.Gauge(self, style=wx.GA_HORIZONTAL)
wrap = wx.BoxSizer()
wrap.Add(self.gobtn, 0, wx.EXPAND|wx.ALL, 10)
wrap.Add(self.prog, 0, wx.EXPAND|wx.ALL, 10)
self.panel.SetSizer(wrap)
self.panel.Fit()
self.SetInitialSize()
self.Bind(wx.EVT_BUTTON, self.Go, self.gobtn)
def Go(self, event):
numwords = 1000000
self.prog.SetValue(0)
for i in range(1, numwords + 1):
progress = int(((float(i) / float(numwords)) * 100) - 1)
self.prog.SetValue(progress)
print "Done"
if __name__ == "__main__":
app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()
因此,实际上,您正在通过长时间运行的任务阻塞GUI线程。在某些平台和/或计算机上,它可能运行良好,也可能无法正常运行。在
还要注意,与您的例子相反:
根据经验,每一个看起来像这样的方法应该只运行几毫秒。在
编辑:我在Windows7上观察到的另一件事。在您调用
self.prog.SetValue()
时,仪表开始增长,并在一段时间内增长到指定值。它不会“跳”到那个值,而是缓慢增长,达到设定值。这似乎是Windows7的功能。我不得不关闭性能选项中的“动画控件和窗口内的元素”来消除这种行为。在相关问题 更多 >
编程相关推荐