Paralelismo en PyGTK

Alfredo Cañadas i92fredy en hotmail.com
Mie Jul 13 17:37:02 CEST 2005


He probado con eso que me dices, y sigue sin funcionarme. Vamos, que hace lo 
mismo. Mi problema me parece que es con las ventanas, para poder observar 
varias simultaneamente no encuentro una solución. Lo que ocurre es que hasta 
que no se me ejecuta la función principal, no se me empieza a ejecutar la 
secundaria (la barra de progreso). Gracias


>From: bameda <bameda en gmail.com>
>Reply-To: La lista de python en castellano <python-es en aditel.org>
>To: La lista de python en castellano <python-es en aditel.org>
>Subject: Re: [Python-es] Paralelismo en PyGTK
>Date: Wed, 13 Jul 2005 13:45:23 +0200
>
>Yo lo hice importando la libreria "gobject". esta posee una funcion
>denominada "gobject.idle_add( function, {param})".
>
>Te explico, mi idea era hacer una aplicacion que me alertara cuando mi
>lavadora acabase de realizar la colada (menuda chorrada), pues bien,
>yo debia de realizar una especie de contador hacia atras y cuando este
>llegase a 0 sonara una melodia. Pero yo queria que cuando el contador
>estubiese andando el programa no se me quedase congelado. Pues bien,
>cree una funcion:
>
>////////
>  def lavando(self, z):
>         t = self.get_time()
>         if (self.actual_time == t):
>             return True;
>         else :
>             self.actualice_actual_time(t)
>             s = self.get_washing_machine_timestart()
>             r = self.get_washing_machine_timeremaind()
>             if (r == 0):
>                 self.play_alarm_lava()
>                 self.msg("Tu ropa ya esta mareada del todo (y humecta)!!")
>                 return False; # ya no nos llaman mas
>             else:
>                 d = self.rest_times(t, s)
>                 print (d)
>                 r = self.get_preferences_washing_machine_timeremaind()
>                 r = self.rest_times(r, d)
>                 # print (t, s, d, r)
>                 self.put_value_on_washing_machine_timeremain(r)
>                 return True; # siguen llamandonos
>///////
>
>y luego, cuando puñsasemos el boton de start esto se realizaria como
>si fuese un bucle hasta que devolviera false. Esto queda plasmado en
>la siguiente funcion:
>
>///////
>def on_botton1_clicked(self,widget):
>         t = self.put_value_on_washing_machine_start_and_stop()
>         v = self.get_preferences_washing_machine_timeremaind()
>         self.put_value_on_dryer_timeremain(v)
>         gobject.idle_add(self.lavando, ())
>///////
>
>Esto me lo comentaron en esta lista, A continuacion te pongo el mail
>que mande y la contestacion por si el ejemplo que a mi me pusieron te
>resulta mas comodo de entender(seguro que si)
>
>**********Mi email ***********************
>Hola en primer lugar saludar a toda la lista ya que soy nuevo en ella,
>este es mi primer mensaje y espero que entre todos encontremos una
>solución. Trataré de explicarme lo mejor que pueda:
>
>Estoy iniciandome en python y tras haberme leído algún que otro manual
>y haber asistido a alguna que otra charla (concretamente a 2, una de
>programacion en python y otra de python + GTK) decidí hacer mi primera
>aplicación gráfica. Algo facilito pensé y como en ese momento estada
>dedicandome a una lavor doméstica que todos los que estudiamos fuera
>de casa padecemos (me refiero a hacer la colada) pues decidi hacer una
>aplicación que me alertara cuando la lavadora acabara y extenderlo a
>la secadora.
>
>Pues bien, sabiendo el tiempo de duración de ambos cacharros, buscando
>dos archivitos de audio molones yn tirando algunas lineas de código
>parecia que todo era pan comido.
>
>Instalé Glade para currarme el tema del GTK y tire mi código que
>aparentemente tira bien. Para reproducir el archivo de audio use el
>mpg321. Mi algoritmo de la aplicación es muy sencillo: en primer lugar
>obtengo la hora de inicio al pulsar al boton de comenzar, le sumo el
>tiempo que tarda la lavadora en dejar mi ropa limpita y muestro ambos
>tiempos en mi aplicación. Simultaneamente una tupla, que contiene la
>h, min y seg que utiliza la lavadora, va disminuyendo segundo a
>segundo. Para ello voy leyendo (con un bucle) la hora actual y cuando
>varía un seg con la anterior esta tupla se modifica. Así hasta que
>llegue a 0 que será cuando suene la alarma avisandonos de que ya
>podemos ir a meter la ropa a la secadora.
>
>Pues bien, mi problema es que los campos en mi aplicación gráfica no
>se actualizan hasta el fina, aunque yo dentro del bucle el contador
>hacia atrás lo actualizo en cada iteración, y además durante la
>ejecución de el bucle no puedo hacer nada más. No puedo, por ejemplo
>crear un boton que me interrumpa el bucle.
>
>Mi pregunta es ¿cómo puedo implementar mi búcle para que me actualice
>la informacion en cada iteración? y ¿cómo puedo hacer para que esta
>función se ejecute en "segundo plano"?. Haber si alguin me puede
>iluminar o conducirme hacia un poco de documentación que me resuelva
>mis dudas.
>
>Aquí os dejo la función en discordia y algo más de código:
>
>class GUI:
>    def __init__(self):
>    def start_preferences(self):
>    def get_time(self):
>    def play_alarm_lava(self):
>    def play_alarm_seca(self):
>    def add_times(self, t1, t2):
>    def rest_times(self, t1, t2):
>    def put_value_on_secadora_start_and_stop(self):
>    def put_value_on_secadora_timeremain(self, t1, t2, t3):
>        if (self.secadora_entry_timeremaind_heure.get_text() != t1):
>            self.secadora_entry_timeremaind_heure.set_text(str(t1))
>        if (self.secadora_entry_timeremaind_minute.get_text() != t2):
>            self.secadora_entry_timeremaind_minute.set_text(str(t2))
>        if (self.secadora_entry_timeremaind_second.get_text() != t3):
>            self.secadora_entry_timeremaind_second.set_text(str(t3))
>    def put_value_on_lavadora_start_and_stop(self):
>    def put_value_on_lavadora_timeremain(self, t1, t2, t3):
>    # Widgets actions
>    def on_window_destroy(self, widget):
>    def on_botton3_clicked(self,widget):
>        t = self.put_value_on_secadora_start_and_stop() # Da la hora
>de inicio además
>        v = 
>int(self.preferences_entry_secadora_timeremaind_heure.get_text()),
>int(self.preferences_entry_secadora_timeremaind_minute.get_text()),
>int(self.preferences_entry_secadora_timeremaind_second.get_text())
>        self.put_value_on_secadora_timeremain(v[0], v[1], v[2])
>        fin = 'false'
>        while(fin == 'false' ):
>            oldt = t
>            t = self.get_time()
>            d = self.rest_times(t, oldt)
>            v = self.rest_times(v, d)
>            if (v[2] == 0 ):
>               if( v [1] == 0):
>                  if( v [0] ==0 ):
>                    fin = 'true'
>            print (v)
>            if (d[2] > 0):
>                self.put_value_on_secadora_timeremain(v[0], v[1], v[2])
>        self.play_alarm_seca()
>
>    def on_botton1_clicked(self,widget):
>if (__name__ == "__main__"):
>        gui = GUI()
>        gtk.main()
>
>
>Gracias de antemano. Un saludo.
>********************************************
>
>**********Contyestacion*****************
>Hola David,
>
>para lo que tu quieres yo usaria las funciones idle (funciones ociosas).
>GTK+ llama a estas funciones siempre que no tenga nada mejor que hacer.
>Asi, puedes usar una de estas funciones para comprobar si tu lavadora ya
>ha terminado de lavar la ropa. Algo como esto:
>
>import pygtk
>pygtk.require('2.0')
>import gtk
>import gobject
>import time
>
># esto es lo que tarda tu super lavadora
>INTERVALO_TIEMPO = 60 * 5  # 5 minutos
>
># funcion de ayuda para mostrar un cuadro de dialogo
>def msg(text):
>    d = gtk.MessageDialog(None,
>                          gtk.DIALOG_MODAL |
>gtk.DIALOG_DESTROY_WITH_PARENT,
>                          gtk.MESSAGE_WARNING,
>                          gtk.BUTTONS_OK,
>                          text)
>    d.run()
>    d.destroy()
>    gtk.main_quit()
>
># funcion que se llama constantemente para comprobar si ha pasado el
>tiempo
>def comprueba_tiempo(hora_limite):
>    hora_actual = time.time()
>    if hora_limite < hora_actual:
>        msg("Tu ropa se esta pudriendo!!!")
>        return False # ya no nos llaman mas
>
>    return True # siguen llamandonos
>
>if __name__ == '__main__':
>    w = gtk.Window()
>    w.connect('destroy', gtk.main_quit)
>
>    label = gtk.Label('Lavando la ropa...')
>    w.add(label)
>    w.show_all()
>
>    hora_limite = time.time() + INTERVALO_TIEMPO
>    # instalo la funcion ociosa
>    gobject.idle_add(comprueba_tiempo, hora_limite)
>
>    gtk.main()
>
>
>Como ves en el codigo, si tu funcion idle devuelve True, GTK la seguira
>llamando. Si devuelve False, ya no la llamara mas.
>
>Como ves, el ejemplo es muy sencillo, pero explica lo de las funciones
>idle que creo que es lo que mas te conviene en este caso.
>
>Un saludo
>
>Lorenzo
>--
>Lorenzo Gil Sanchez <lgs en sicem.biz>
>
>********************************************
>
>Bueno despues de esta parrafada espero haberte ayudado en la medida de
>lo posible.
>
>UN SALUDO
>
>--
>____________________________________________
>|
>|    David Barragán Merino
>|    E-mail: bameda en ARROBA@gmail.com
>|    Ingeniería Informática
>|    Universidad Carlos III Madrid
>|____________________________________________
>_______________________________________________
>Python-es mailing list
>Python-es en aditel.org
>http://listas.aditel.org/listinfo/python-es




Más información sobre la lista de distribución Python-es