0

这是我在 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 上我遇到了这个问题。

4

2 回答 2

1

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

但是,如果您只是想不时地任意重置标签,我认为使用 wx.Timer() 会简单得多。

于 2013-04-25T13:33:34.703 回答
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/

于 2013-04-25T08:44:39.610 回答