Saschs Blog
neuster   |   archiv   |   fotos   |   orte   |   suche   |   über
Kommentare deaktiviert

Worker Thread von wxPython GUI

Veröffentlicht: 22. Dezember 2007

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:

?View Code PYTHON
#!/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()