标题: wxpython的线程处理

时间: 2013-11-08 18:47:30

正文:

在大多数的GUI应用程序中,在应用程序的后台中长期执行一个处理过程而不干涉用户与应用程序的其它部分的交互是有好处的。允许后台处理的机制通常是产生一个线程并在该线程中长期执行一个处理过程。

大体上跟 python 的线程处理还是类似的。根据网上搜罗的各种资料,一般意义上说 wxpython 为线程安全专门提供了三个函数来处理,三个安全线程如下:

其中,wx.CallLater 是最抽象的线程安全函数,其次是callAfter,最后是PostEvent。

        转载请注明出处 http://blog.hickwu.com/posts/304 by Hick

实际上,试了下不使用这三个函数也可以基本达到线程和主线程之间的通讯,下面是我不使用这三个函数和使用其中的 wx.CallAfter 同时达到通讯目的的实例,通过执行观察输出结果,可以看到 wx.CallAfter 的调用是在主线程中进行的:

#!/usr/bin/env python
#coding=utf8

import time
import wx
import threading

class TestThread(threading.Thread):
    """示例线程"""
     #----------------------------------------------------------------------
    def __init__(self, window):
        """初始化工作线程: 把主窗口传进来"""
        threading.Thread.__init__(self)
        self.label = window.displayLbl
        self.label.SetLabel(u"%s \n线程初始化: %s  时间: %s" % 
            (self.label.GetLabel(), threading.currentThread().getName(), time.time()))
        self.start() 

    #----------------------------------------------------------------------
    def run(self):
        """执行工作线程"""
        tname = threading.currentThread().getName()
        for i in range(2):
            time.sleep(5)
            # wx.CallAfter(self.postTime, i)
            self.label.SetLabel(u"%s \n线程 %s , 第 %s 次循环于 %s" % 
                (self.label.GetLabel(), tname, i + 1, time.time()))
        time.sleep(5)
        wx.CallAfter(self.postTime, u" %s 线程结束" % tname)

    #----------------------------------------------------------------------
    def postTime(self, msg):
        """跟主进程通信"""
        tname = threading.currentThread().getName()
        self.label.SetLabel(u"%s \n线程 %s 收到消息 %s 时间 %s" % 
            (self.label.GetLabel(), tname, msg, time.time()))


class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, u"线程")

        panel = wx.Panel(self, wx.ID_ANY)
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.btn = btn = wx.Button(panel, label=u"创建一个线程(别点太多,3个就够了)")
        btn.Bind(wx.EVT_BUTTON, self.onButton)
        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)

        self.displayLbl = wx.StaticText(panel, label=u"下面显示线程信息:")
        sizer.Add(self.displayLbl, 0, wx.ALL|wx.LEFT, 5)

        panel.SetSizer(sizer)

    def onButton(self, event):
        # 按一次按钮启动一个线程
        TestThread(self)  

if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

查看更多文章
分享到:


分享到: