Um die GUI für längere Berechnungen nicht zu blockieren sollte man einen neuen Thread erzeugen. Dieser kann die GUI nach dem Observer Pattern über seinen aktuellen Zustand informieren:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import os, sys, time
import threading
import wx.lib.newevent
[wxID_FRAME1, wxID_FRAME1BT_START,
] = [wx.NewId() for _init_ctrls in range( 2 )]
modules ={'Frame1': [1, 'Main frame of Application', u'Frame1.py']}
( NewStatusEvent, EVT_NEW_STATUS ) = wx.lib.newevent.NewEvent()
class BoaApp( wx.App ):
def OnInit( self ):
self.main = Frame1( None )
self.main.Show()
self.SetTopWindow( self.main )
return True
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( 470, 586 ), size=wx.Size( 400, 250 ),
style=wx.DEFAULT_FRAME_STYLE, title='Working Thread' )
self.SetClientSize( wx.Size( 392, 216 ) )
self.bt_start = wx.Button( id=wxID_FRAME1BT_START,
label=u'run Worker', name=u'bt_start', parent=self,
pos=wx.Point( 264, 160 ), size=wx.Size( 107, 23 ), style=0 )
self.bt_start.Bind( wx.EVT_BUTTON, self.OnBt_startButton,
id=wxID_FRAME1BT_START )
def __init__( self, parent ):
self._init_ctrls( parent )
# worker thread
self.myworkingthread = None
# bind event from worker thread to event-handler method
self.Bind( EVT_NEW_STATUS, self.updateStatus )
def updateStatus( self, event ):
"""Eventhandler."""
print(event.current_state )
def OnBt_startButton( self, event ):
self.myworkingthread = MyWorkingThread( self )
# add observer
self.myworkingthread.add_event_recipient( self )
self.myworkingthread.start()
def __del__( self ):
self.myworkingthread.stop()
self.myworkingthread.join()
class MyWorkingThread( threading.Thread ):
def __init__( self, referrer ):
threading.Thread.__init__( self )
self.cancel = threading.Event()
self.gui = referrer
# observer list
self.event_recipients = []
self.running = True
def add_event_recipient( self, recipient ):
"""add observer."""
self.event_recipients.append( recipient )
def run( self ):
# do a lot of work
while self.running:
evt = NewStatusEvent()
evt.current_state = 'working…'
# notify observers
for recipient in self.event_recipients:
if recipient:
wx.CallAfter( recipient.ProcessEvent, evt )
time.sleep(1)
def stop( self ):
# Cleanup
self.cancel.set()
self.event_recipients = []
self.running = False
def main():
application = BoaApp( 0 )
application.MainLoop()
if __name__ == '__main__':
main()