Philippe, I just wrote the code following the example you provided. The image location can be controlled with the data from socket client. But only one thing confuse me. When the image keeps moving to a new location, the image at a "old" location is not deleted and is left behind in the frame. Do you know what is going on with it? The location of image is processed in "def OnResult(self,event):" and is initialized in "def __init__(self, parent, id):" of "class MainFrame" ( See the code attached).
Thanks a lot. ouyang ################################################## import time from threading import * import wx, string from socket import * from Main import opj host = "192.168.0.2" port = 21567 buf = 1024 addr = (host,port) UDPSock = socket(AF_INET,SOCK_DGRAM) UDPSock.bind(addr) # Button definitions ID_START = wx.NewId() ID_STOP = wx.NewId() # Define notification event for thread completion EVT_RESULT_ID = wx.NewId() def EVT_RESULT(win, func): """Define Result Event.""" win.Connect(-1, -1, EVT_RESULT_ID, func) class ResultEvent(wx.PyEvent): """Simple event to carry arbitrary result data.""" def __init__(self, data): """Init Result Event.""" wx.PyEvent.__init__(self) self.SetEventType(EVT_RESULT_ID) d = string.split(data,'-') self.data = [string.atoi(d[0]),string.atoi(d[1]),string.atof(d[2])] # Thread class that executes processing class WorkerThread(Thread): """Worker Thread Class.""" def __init__(self, notify_window): """Init Worker Thread Class.""" Thread.__init__(self) self._notify_window = notify_window self._want_abort = 0 # This starts the thread running on creation, but you could # also make the GUI thread responsible for calling this self.start() def run(self): """Run Worker Thread.""" # This is the code executing in the new thread. Simulation of # a long process (well, 10s here) as a simple loop - you will # need to structure your processing so that you periodically # peek at the abort variable while 1: if self._want_abort: wx.PostEvent(self._notify_window, ResultEvent(None)) #return break else: data,addr = UDPSock.recvfrom(buf) if not data: print "Client has exited!" break else: print "\nReceived message '", data,"'" wx.PostEvent(self._notify_window, ResultEvent(data)) # Close socket UDPSock.close() def abort(self): """abort worker thread.""" # Method for use by main thread to signal an abort self._want_abort = 1 # GUI Frame class that spins off the worker thread class MainFrame(wx.Frame): """Class MainFrame.""" def __init__(self, parent, id): """Create the MainFrame.""" wx.Frame.__init__(self, parent,id, title='monitoring system', size=(500,600)) self.panel = wx.Panel(self,-1,(0,0),(500,600)) self.bmp = wx.Image(opj('bitmaps/image.bmp'), wx.BITMAP_TYPE_BMP) self.bmp.SetMask(True) # Dumb sample frame with two buttons wx.Button(self.panel, ID_START, 'Start', pos=(0,0)) wx.Button(self.panel, ID_STOP, 'Stop', pos=(0,50)) self.status = wx.StaticText(self.panel, -1, '', pos=(0,100)) x = 50 y = 150 angle = 1.23 bmp = self.bmp.Rotate(angle, (x,y), True,None) bmp = bmp.ConvertToBitmap() wx.StaticBitmap(self.panel, -1, bmp, (x, y), (bmp.GetWidth(), bmp.GetHeight())) self.Bind(wx.EVT_BUTTON, self.OnStart, id=ID_START) self.Bind(wx.EVT_BUTTON, self.OnStop, id=ID_STOP) # Set up event handler for any worker thread results EVT_RESULT(self,self.OnResult) # And indicate we don't have a worker thread yet self.worker = None def OnStart(self, event): """Start Computation.""" # Trigger the worker thread unless it's already busy if not self.worker: self.status.SetLabel('Starting computation') self.worker = WorkerThread(self) def OnStop(self, event): """Stop Computation.""" # Flag the worker thread to stop if running if self.worker: self.status.SetLabel('Trying to abort computation') self.worker.abort() def OnResult(self, event): """Show Result status.""" if event.data is None: # Thread aborted (using our convention of None return) self.status.SetLabel('Computation aborted') else: # Process results here self.status.SetLabel('Computation Result: %s-%s-%s' % (event.data[0], event.data[1],event.data[2])) angle = event.data[2] x = event.data[0] y = event.data[1] bmp = self.bmp.Rotate(angle, (x,y), True,None) bmp = bmp.ConvertToBitmap() wx.StaticBitmap(self.panel, -1, bmp, (x, y), (bmp.GetWidth(), bmp.GetHeight())) # In either event, the worker is done self.worker = None class MainApp(wx.App): """Class Main App.""" def OnInit(self): """Init Main App.""" self.frame = MainFrame(None, -1) self.frame.Show(True) self.SetTopWindow(self.frame) return True if __name__ == '__main__': app = MainApp(0) app.MainLoop() ########################################################## Philippe Martin 写道: > Philippe Martin wrote: > > > zxo102 wrote: > > > >> Hi everyone, > >> I am using a python socket server to collect data from a socket > >> client and then control a image location ( wxpython) with the data, > >> i.e. moving the image around in the wxpython frame. > >> But the "app.MainLoop()" in wxpython looks like conflicting with > >> the "while 1:" in socket server. After I commented the > >> "app.MainLoop()", everything is working except two things: > >> 1. if I click anywhere on the screen with the mouse, the image is > >> gong and only the empty frame( or panel) is left. > >> 2. if I don't touch anything, the image is being moved around but > >> the previous images are left behind in the panel. > >> I guess that may be caused by "app.MainLoop()" commented. > >> Anybody knows how to make the two things work together? I really > >> appreciate your help. > >> My sample code is modified based on the wxpython demo: image.py. > >> socket client is also attached for your reference. > >> > >> Ouyang > >> > >> ################ socket server with wxpython ############## > >> > >> from Main import opj > >> import wx,string > >> class MMCS(wx.Frame): > >> def __init__(self): > >> self.bmp = wx.Image(opj('bitmaps/image.bmp'), > >> wx.BITMAP_TYPE_BMP) > >> self.bmp.SetMask(True) > >> wx.Frame.__init__(self, parent=None, title='monitoring system', > >> size=(500,600)) > >> self.panel = wx.Panel(self,-1) > >> > >> def monitor(self,x,y,angle): > >> bmp = self.bmp.Rotate(angle, (x,y), True,None) > >> bmp = bmp.ConvertToBitmap() > >> > >> wx.StaticBitmap(self.panel, -1, bmp, (x, y), (bmp.GetWidth(), > >> bmp.GetHeight())) > >> del bmp > >> > >> app = wx.PySimpleApp() > >> frame = MMCS() > >> frame.Show() > >> frame.monitor(50,10,0.0) > >> #app.MainLoop() > >> > >> # Server program > >> from socket import * > >> # Set the socket parameters > >> host = "192.168.0.2" > >> port = 21567 > >> buf = 1024 > >> addr = (host,port) > >> > >> # Create socket and bind to address > >> UDPSock = socket(AF_INET,SOCK_DGRAM) > >> UDPSock.bind(addr) > >> > >> # Receive messages > >> while 1: > >> data,addr = UDPSock.recvfrom(buf) > >> if not data: > >> print "Client has exited!" > >> break > >> else: > >> print "\nReceived message '", data,"'" > >> d = string.split(data, '-') > >> > >> frame.monitor(string.atoi(d[0]),string.atoi(d[1]),string.atof(d[2])) > >> if data == 'END': > >> print "end of moving the ship" > >> > >> # Close socket > >> UDPSock.close() > >> > >> ############# socket client ######################> > >> rom socket import * > >> import time > >> > >> # Set the socket parameters > >> host = "192.168.0.2" > >> port = 21567 > >> buf = 1024 > >> addr = (host,port) > >> > >> # Create socket > >> UDPSock = socket(AF_INET,SOCK_DGRAM) > >> def_msg = "===Enter message to send to server==="; > >> print "\n",def_msg > >> > >> # Send messages > >> while (1): > >> for i in range(100): > >> time.sleep(1) > >> data = "50-100-%s"%(0.1*i) > >> if(UDPSock.sendto(data,addr)): > >> print "Sending message '",data,"'....." > >> # Close socket > >> UDPSock.close() > > > > > > If you get rid of app.MaiLoop(), you basically get rid of all GUI events. > > You need to have you server in a separate thread. > > > > Philippe > PS: > > http://wiki.wxpython.org/index.cgi/LongRunningTasks -- http://mail.python.org/mailman/listinfo/python-list