wxPython异步调用实现

来源:互联网 发布:苹果游戏辅助软件 编辑:程序博客网 时间:2024/04/29 04:11

标题不一定对,

最近遇到了个问题,利用wxPython和boa画了个GUI,通过该GUi去执行一个花蛮长时间才能做完的应用,结果UI就hang住了。

这问题和我以前用C#实现的取Windows控件属性遇到的问题类似,反正就是需要用过异步调用的办法来解决这个问题


在借鉴了一些代码片段之后,我也改出了异步的调用,代码片段如下


#Boa:Frame:Frame1import wximport osimport subprocessfrom threading import Threadfrom wx.lib.pubsub import Publisherdef create(parent):    return Frame1(parent)[wxID_FRAME1, wxID_FRAME1BUTTON1, wxID_FRAME1CHECKBOX1, wxID_FRAME1CHECKBOX2, wxID_FRAME1CHECKBOX3, wxID_FRAME1CHECKBOX4, wxID_FRAME1CHECKBOX5, wxID_FRAME1CHECKBOX6, wxID_FRAME1CLOSEB, wxID_FRAME1PANEL1, wxID_FRAME1STATICTEXT1, wxID_FRAME1STATICTEXT2, wxID_FRAME1TEXTCTRL1, wxID_FRAME1TEXTCTRL2,] = [wx.NewId() for _init_ctrls in range(14)]########################################################################class TestThread(Thread):    """Test Worker Thread Class."""    #----------------------------------------------------------------------    def __init__(self,command):        """Init Worker Thread Class."""        Thread.__init__(self)        self.command = command        self.start()    # start the thread    #----------------------------------------------------------------------    def run(self):        """Run Worker Thread."""        # This is the code executing in the new thread.        self.data = subprocess.Popen((self.command),stdout = subprocess.PIPE)        self.logg = self.data.stdout.read()        self.fd = open('c:\\test\\log.txt','a+')        self.fd.write(self.logg)        self.fd.close()        wx.CallAfter(Publisher().sendMessage, "update", "Test Finished!")    #----------------------------------------------------------------------##    def postTime(self, amt):##        """##        Send time to GUI##        """##        amtOfTime = (amt + 1) * 10##        Publisher().sendMessage("update", amtOfTime)########################################################################class Frame1(wx.Frame):    def _init_ctrls(self, prnt):        # generated method, don't edit        wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,              pos=wx.Point(432, 348), size=wx.Size(285, 269),              style=wx.DEFAULT_FRAME_STYLE, title='ViaB Automation')        self.SetClientSize(wx.Size(277, 242))        self.lanarrary = []        self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,              pos=wx.Point(0, 0), size=wx.Size(277, 242),              style=wx.TAB_TRAVERSAL)        self.CloseB = wx.Button(id=wxID_FRAME1CLOSEB, label=u'Run',              name=u'CloseB', parent=self.panel1, pos=wx.Point(16, 160),              size=wx.Size(75, 23), style=0)        self.CloseB.Bind(wx.EVT_BUTTON, self.OnCloseButton,              id=wxID_FRAME1CLOSEB)        self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1',              parent=self.panel1, pos=wx.Point(16, 40), size=wx.Size(240, 21),              style=0, value='\\\\10.158.128.200\\Common\\build\\VDI-in-a-Box\\5.3.blue\\20130918\\XEN\\vdiManager_Xen_v5_3Blue_Sept18.xva')        self.checkBox1 = wx.CheckBox(id=wxID_FRAME1CHECKBOX1, label=u'German',              name='checkBox1', parent=self.panel1, pos=wx.Point(16, 104),              size=wx.Size(70, 13), style=0)        self.checkBox1.SetValue(False)        self.checkBox2 = wx.CheckBox(id=wxID_FRAME1CHECKBOX2, label=u'French',              name='checkBox2', parent=self.panel1, pos=wx.Point(112, 104),              size=wx.Size(70, 13), style=0)        self.checkBox2.SetValue(False)        self.checkBox3 = wx.CheckBox(id=wxID_FRAME1CHECKBOX3, label=u'Spanish',              name='checkBox3', parent=self.panel1, pos=wx.Point(200, 104),              size=wx.Size(70, 13), style=0)        self.checkBox3.SetValue(False)        self.checkBox4 = wx.CheckBox(id=wxID_FRAME1CHECKBOX4, label=u'Japanese',              name='checkBox4', parent=self.panel1, pos=wx.Point(16, 136),              size=wx.Size(70, 13), style=0)        self.checkBox4.SetValue(False)        self.checkBox5 = wx.CheckBox(id=wxID_FRAME1CHECKBOX5, label=u'SChinese',              name='checkBox5', parent=self.panel1, pos=wx.Point(112, 136),              size=wx.Size(70, 13), style=0)        self.checkBox5.SetValue(False)        self.checkBox6 = wx.CheckBox(id=wxID_FRAME1CHECKBOX6, label=u'English',              name='checkBox6', parent=self.panel1, pos=wx.Point(200, 136),              size=wx.Size(70, 13), style=0)        self.checkBox6.SetValue(False)        self.button1 = wx.Button(id=wxID_FRAME1BUTTON1, label=u'Close',              name='button1', parent=self.panel1, pos=wx.Point(112, 160),              size=wx.Size(75, 23), style=0)        self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,              id=wxID_FRAME1BUTTON1)        self.staticText1 = wx.StaticText(id=wxID_FRAME1STATICTEXT1,              label='1. Input the UNC path of the Viab XVA', name='staticText1', parent=self.panel1,              pos=wx.Point(16, 16), size=wx.Size(254, 13), style=0)        self.staticText2 = wx.StaticText(id=wxID_FRAME1STATICTEXT2,              label='2. Select language you want to test', name='staticText2', parent=self.panel1,              pos=wx.Point(16, 80), size=wx.Size(254, 13), style=0)        self.textCtrl2 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL2, name='textCtrl2',              parent=self.panel1, pos=wx.Point(16, 200), size=wx.Size(240, 16),              style=0, value='')        self.textCtrl2.SetEditable(False)    def __init__(self, parent):        self._init_ctrls(parent)        Publisher().subscribe(self.updateDisplay, "update")    def OnCloseButton(self, event):##        self.path=self.textCtrl1.GetValue()##        if self.checkBox1.IsChecked():##            self.lanarrary.append('de')##        if self.checkBox2.IsChecked():##            self.lanarrary.append('fr')##        if self.checkBox3.IsChecked():##            self.lanarrary.append('es')##        if self.checkBox4.IsChecked():##            self.lanarrary.append('ja')##        if self.checkBox5.IsChecked():##            self.lanarrary.append('sc')##        if self.checkBox6.IsChecked():##            self.lanarrary.append('en')##        self.strlan = self.array_to_string(self.lanarrary)##        self.str1 = "python c:\\test\\main.py "+self.path+self.strlan        self.commandstr=self.ComposeCommand()        self.textCtrl2.SetValue(self.commandstr)        self.lanarrary = []        TestThread(self.str1)##        self.displayLbl.SetLabel("Thread started!")        self.CloseB = event.GetEventObject()        self.CloseB.Disable()    def ComposeCommand(self):        self.path=self.textCtrl1.GetValue()        if self.checkBox1.IsChecked():            self.lanarrary.append('de')        if self.checkBox2.IsChecked():            self.lanarrary.append('fr')        if self.checkBox3.IsChecked():            self.lanarrary.append('es')        if self.checkBox4.IsChecked():            self.lanarrary.append('ja')        if self.checkBox5.IsChecked():            self.lanarrary.append('sc')        if self.checkBox6.IsChecked():            self.lanarrary.append('en')        self.strlan = self.array_to_string(self.lanarrary)        self.str1 = "python c:\\test\\main.py "+self.path+self.strlan        return self.str1##        self.CloseB.Disable()##        self.data = subprocess.Popen((self.str1),stdout = subprocess.PIPE)##        self.logg = self.data.stdout.read()##        self.fd = open('c:\\test\\log.txt','a+')##        self.fd.write(self.logg)##        self.fd.close()##        self.CloseB.Enable()    def array_to_string(self, alist):        self.str0 = ""        for item in alist:            self.str0 = self.str0+" "+item        return self.str0    def OnButton1Button(self, event):        self.Close(True)    def updateDisplay(self, msg):        """        Receives data from thread and updates the display        """        t = msg.data        if isinstance(t, int):            #self.displayLbl.SetLabel("Time since thread started: %s seconds" % t)            pass        else:            self.CloseB.Enable()            self.textCtrl2.SetValue("%s" % t)