wxpython:time.sleep()阻止mac上的GUI

时间:2013-04-25 08:14:52

标签: python user-interface wxpython

这是我在Mac上面对wxpython的奇怪问题。虽然这在Windows7上使用wxpython完全正常。我正试图在time.sleep()之前和之后更新wx.StaticText标签:

self.lblStatus = wx.StaticText(self, label="", pos=(180, 80))
self.lblStatus.SetLabel("Processing....")
time.sleep(10)

在上面的代码中,标签“Processing ...”在time.sleep()完成10秒后才会显示。即SetLabel在10秒后生效。

在Windows7 / wxpython上按预期工作,但在Mac上我遇到了问题。

2 个答案:

答案 0 :(得分:1)

我从未见过time.sleep()不阻止Windows上的GUI。睡眠功能阻止wx的主循环,简单明了。正如JHolta所提到的,假设您使用线程安全方法,例如wx.CallAfter,wx.CallLater或wx.PostEvent,您可以将睡眠放入线程并从那里更新GUI。

但是,如果你只想偶尔任意重置一个标签,我认为使用wx.Timer()要简单得多。

答案 1 :(得分:0)

wxPython gui是一个循环,让代码的一部分进入睡眠状态而不会导致gui睡眠,需要多线程。

我会写一个调用线程函数的函数,现在这是一个肮脏的例子,但应该告诉你需要做什么:

import wx
from threading import Thread
import time
from wx.lib.pubsub import setuparg1
from wx.lib.pubsub import pub as Publisher

class Example(wx.Frame):      
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        self.SetTitle('This is a threaded thing')

        self.st1 = wx.StaticText(self, label='', pos=(30, 10))

        self.SetSize((250, 180))
        self.Centre()
        self.Show(True) 

        self.Bind(wx.EVT_MOVE, self.OnMove)
        # call updateUI when the thread returns something
        Publisher.subscribe(self.updateUI, "update")        

    def OnMove(self, evt):
        ''' On frame movement call thread '''
        x, y = evt.GetPosition()
        C = SomeClass()
        C.runthread(x, y)

    def updateUI(self, evt):
      ''' Update label '''
      data = evt.data
      self.st1.SetLabel(data)  

class SomeClass:
    def runthread(self,  x,y):
        ''' Start a new thread '''
        t = Thread(target=self._runthread, args=(x,y,))
        t.start()

    def _runthread(self, x,y):
        ''' this is a threaded function '''
        wx.CallAfter(Publisher.sendMessage, "update", "processing...")
        time.sleep(3)
        wx.CallAfter(Publisher.sendMessage, "update", "%d, %d" % (x, y))


def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()

if __name__ == '__main__':
    main()

现在,一旦您尝试移动“框架”/窗口,线程就会被初始化,并且将返回窗口的当前位置。

wx.CallAfter()是对GUI线程的线程安全调用,仅在GUI线程准备好接收时才发送数据。 Publisher-module简化了将数据发送到我们的线程的任务。

我建议您阅读:http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/