Foros del Web » Programando para Internet » Python »

Thead wxpython

Estas en el tema de Thead wxpython en el foro de Python en Foros del Web. Bueno, tengo un formulario con una lista, cuando se va selecionando los distintos items, se corre la funcion x esta llama a otra funcion load_Fotos ...
  #1 (permalink)  
Antiguo 02/08/2010, 21:31
 
Fecha de Ingreso: abril-2008
Mensajes: 68
Antigüedad: 16 años, 7 meses
Puntos: 0
Thead wxpython

Bueno, tengo un formulario con una lista, cuando se va selecionando los distintos items, se corre la funcion x esta llama a otra funcion load_Fotos que esta llama a download. Esta ultima baja unos archivos de la web, lo cual tarda, por eso hasta que no termina no devuelve el control del programa.
Tendria que crear un thread verdad? para correr la funcion download, cual seria la manera correcta. estas son las funciones.

Código:
def x(self):
        self.Foto.Load_Fotos(art.Foto)
Código:
    def Load_Fotos(self,fotos):
        paneles = [self.Foto,self.Foto1,self.Foto2,self.Foto3]
        for p in paneles:
            p.pic = self.il.NOPIC
        bi = wx.BusyInfo("Cargando imagenes, espere por favor...")
        for i,f in enumerate(fotos):
            dir = md.Func.download(f)
            if dir != False:
                if i == 0:
                    self.Load_Foto(self.Foto1, dir)
                if i == 1:
                    self.Load_Foto(self.Foto2, dir)
                if i == 2:
                    self.Load_Foto(self.Foto3, dir)
        self.Foto.pic = self.Foto1.pic
        self.Refresh()
        bi.Destroy()
Código:
def download(url):
    import urllib
    try:
        image = urllib.URLopener()
        name = url.split('/')[-1]
        dir = c.TmpPath + name
        image.retrieve(url,dir)
        return dir
    except: 
        return False
osea en vez de tener el wx.busyinfo me gustaria tener el control del programa.
Saludos y muchas gracias
  #2 (permalink)  
Antiguo 03/08/2010, 14:08
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 8 meses
Puntos: 1360
Respuesta: Thead wxpython

De eso se trata wx.BusyInfo, bloquear el programa hasta que termine de calcular. Si no quieres que se bloquee solo cámbialo por algún MessageDialog

Sin embargo puedes usar threads para acelerar la descarga de los archivos.
  #3 (permalink)  
Antiguo 03/08/2010, 17:12
 
Fecha de Ingreso: abril-2008
Mensajes: 68
Antigüedad: 16 años, 7 meses
Puntos: 0
Respuesta: Thead wxpython

En realidad le puse el busyinfo para que el programa no paresca colgado, porque sin eso tampoco tenes el control del programa hasta que termine de bajar las fotos, porque el evento se llama al cambiar de item del control list.
Por eso me gustaria hacerlo con threads para que por mas que no halla terminado de bajar las fotos se pueda cambiar de item y cancele la descarga. Es un ABM de productos y en el list estan cargados los codigos y descripciones a medida que te vas moviendo consulta en la base la descripcion, precio, codigo, etc y baja las fotos de un server osea en la base dice: http://ejemplo.com/foto1.jpg,dir2,... y descarga cada una...

pero cual es la mejor manera de usar theadrs, una para cada foto? una para el bucle que baja la foto?
  #4 (permalink)  
Antiguo 04/08/2010, 09:03
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 8 meses
Puntos: 1360
Respuesta: Thead wxpython

Aquí hay varios ejemplos

Código Python:
Ver original
  1. import time
  2. from threading import *
  3. import wx
  4.  
  5. # Button definitions
  6. ID_START = wx.NewId()
  7. ID_STOP = wx.NewId()
  8.  
  9. # Define notification event for thread completion
  10. EVT_RESULT_ID = wx.NewId()
  11.  
  12. def EVT_RESULT(win, func):
  13.     """Define Result Event."""
  14.     win.Connect(-1, -1, EVT_RESULT_ID, func)
  15.  
  16. class ResultEvent(wx.PyEvent):
  17.     """Simple event to carry arbitrary result data."""
  18.     def __init__(self, data):
  19.         """Init Result Event."""
  20.         wx.PyEvent.__init__(self)
  21.         self.SetEventType(EVT_RESULT_ID)
  22.         self.data = data
  23.  
  24. # Thread class that executes processing
  25. class WorkerThread(Thread):
  26.     """Worker Thread Class."""
  27.     def __init__(self, notify_window):
  28.         """Init Worker Thread Class."""
  29.         Thread.__init__(self)
  30.         self._notify_window = notify_window
  31.         self._want_abort = 0
  32.         # This starts the thread running on creation, but you could
  33.         # also make the GUI thread responsible for calling this
  34.         self.start()
  35.  
  36.     def run(self):
  37.         """Run Worker Thread."""
  38.         # This is the code executing in the new thread. Simulation of
  39.         # a long process (well, 10s here) as a simple loop - you will
  40.         # need to structure your processing so that you periodically
  41.         # peek at the abort variable
  42.         for i in range(10):
  43.             time.sleep(1)
  44.             if self._want_abort:
  45.                 # Use a result of None to acknowledge the abort (of
  46.                 # course you can use whatever you'd like or even
  47.                 # a separate event type)
  48.                 wx.PostEvent(self._notify_window, ResultEvent(None))
  49.                 return
  50.         # Here's where the result would be returned (this is an
  51.         # example fixed result of the number 10, but it could be
  52.         # any Python object)
  53.         wx.PostEvent(self._notify_window, ResultEvent(10))
  54.  
  55.     def abort(self):
  56.         """abort worker thread."""
  57.         # Method for use by main thread to signal an abort
  58.         self._want_abort = 1
  59.  
  60. # GUI Frame class that spins off the worker thread
  61. class MainFrame(wx.Frame):
  62.     """Class MainFrame."""
  63.     def __init__(self, parent, id):
  64.         """Create the MainFrame."""
  65.         wx.Frame.__init__(self, parent, id, 'Thread Test')
  66.  
  67.         # Dumb sample frame with two buttons
  68.         wx.Button(self, ID_START, 'Start', pos=(0,0))
  69.         wx.Button(self, ID_STOP, 'Stop', pos=(0,50))
  70.         self.status = wx.StaticText(self, -1, '', pos=(0,100))
  71.  
  72.         self.Bind(wx.EVT_BUTTON, self.OnStart, id=ID_START)
  73.         self.Bind(wx.EVT_BUTTON, self.OnStop, id=ID_STOP)
  74.  
  75.         # Set up event handler for any worker thread results
  76.         EVT_RESULT(self,self.OnResult)
  77.  
  78.         # And indicate we don't have a worker thread yet
  79.         self.worker = None
  80.  
  81.     def OnStart(self, event):
  82.         """Start Computation."""
  83.         # Trigger the worker thread unless it's already busy
  84.         if not self.worker:
  85.             self.status.SetLabel('Starting computation')
  86.             self.worker = WorkerThread(self)
  87.  
  88.     def OnStop(self, event):
  89.         """Stop Computation."""
  90.         # Flag the worker thread to stop if running
  91.         if self.worker:
  92.             self.status.SetLabel('Trying to abort computation')
  93.             self.worker.abort()
  94.  
  95.     def OnResult(self, event):
  96.         """Show Result status."""
  97.         if event.data is None:
  98.             # Thread aborted (using our convention of None return)
  99.             self.status.SetLabel('Computation aborted')
  100.         else:
  101.             # Process results here
  102.             self.status.SetLabel('Computation Result: %s' % event.data)
  103.         # In either event, the worker is done
  104.         self.worker = None
  105.  
  106. class MainApp(wx.App):
  107.     """Class Main App."""
  108.     def OnInit(self):
  109.         """Init Main App."""
  110.         self.frame = MainFrame(None, -1)
  111.         self.frame.Show(True)
  112.         self.SetTopWindow(self.frame)
  113.         return True
  114.  
  115. if __name__ == '__main__':
  116.     app = MainApp(0)
  117.     app.MainLoop()

En cuanto al numero de threads depende de cuantos núcleos tenga tu procesador. Ademas de otros factores como si haces alguna sincronización o si esperas alguna entrada o salida.

Aquí una discusión completa sobre el numero optimo de threads

En este caso en particular si solo son 4 fotos le pondría un thread por foto.

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:12.