
Utilización de Threads en Python con Boa Constructor y wxPython GUI
Tiempo total: 0 días con 12:36:46 hrs
Esta publicación trata sobre el uso de líneas de tiempo, timer o Threads en Python utilizando Boa Constructor en GNU/Linux.
IDE
BOA constructor
v0.6.1
A Python IDE and wxPython GUI builder
OS
El código de esta publicación fue utilizado en Ubuntu pues la instalación de Boa Constructor es bastante más fácil utilizando el centro de software en comparación si se utiliza la consola de GNU/Linux en la distribución de Fedora 19.
Plantilla para la utilización de Threads:
import threading import wx class tiempo(threading.Thread): #Constructor def __init__(self): threading.Thread.__init__(self) #Tiempo def run(self): self.procesar() def procesar(self): #código
Para la utilización de este código en cualquier parte de la aplicación, por ejemplo en un Frame y suponiendo que el archivo Python que contiene la clase tiempo mostrado anteriormente es llamado tiempos.py, se utiliza el siguiente código:
from tiempos import tiempo ... def __init__(self, parent): self._init_ctrls(parent) # self.tiempo_ = tiempo() self.tiempo_.start()
Para el código anterior se debe suponer un Frame del IDE Boa Constructor.
Comunicación entre Threads y wxPython GUI
wxPython GUI es la interfaz utilizada en Boa Constructor, el cual puede contener por ejemplo alguno de los siguientes elementos:
Elemento | WxPython GUI |
Texto | wx.TextCtrl |
Etiqueta | wx.StaticText |
Lista de selección | wx.ComboBox |
Lista de texto | wx.ListBox |
Boton | wx.Button |
Para poder utilizar los elementos de esta GUI en los Threads, es necesario que las clases que implementan el tiempo tengan acceso a una variable que contenga los elementos gráficos, para esto se pasa el contenedor al momento de inicializar la clase:
Frame
self.tiempo_ = tiempo(self)
self.tiempo_.start()
Thread
def __init__(self,parent): self.parent=parent def procesar(self): #self.parent
Al momento de simplemente editar alguno de estos elementos desde algún Thread se generara una serie de errores, alguno de estos son:
Llamada simple desde la clase tiempo que implementa los Threads:
self.parent.txt.Clear() self.parent.txt.AppendText("Hola mundo")
Suponiendo que el elemento wx.TextCtrl es llamado txt, la aplicación puede tener algunos o todos de los siguientes errores dependiendo del tipo de implementación que se realiza:
(Python:3809): Pango-CRITICAL **: pango_layout_get_text: assertion `PANGO_IS_LAYOUT (layout)' failed (Python:3830): GLib-GObject-CRITICAL **: g_object_ref: assertion `object->ref_count > 0' failed (Python:3830): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed (Python:3830): LIBDBUSMENU-GLIB-WARNING **: Translation has an invalid value 'I-->D' for default text direction. Defaulting to left-to-right.
Para solucionar este problema, únicamente se utilizan los métodos: wx.PostEvent, wx.CallAfter and wx.CallLater. Para no mostrar información redundante una de las soluciones para este problema es la siguiente línea de código en la clase que implementa el Thread:
#Tiempo def run(self): wx.CallAfter(self.procesar)
En este caso self.procesar es el método que utilizara los elementos GUI de la aplicación.
Implementación de los Threads
Para hacer correr una línea de tiempo, se debe de utilizar la función timer.sleep o bien wx.Sleep, esta última no tiene la precisión en milisegundos que tiene timer.sleep.
Implementación de timer.sleep
import threading, time import wx class tiempo(threading.Thread): #Constructor def __init__(self,parent): self.parent=parent Threading.Thread.__init__(self) #Stop def stop(self): self.i = -10 #Tiempo def run(self): self.i = 1 while self.i > 0: wx.CallAfter(self.procesar) time.sleep(0.1) def procesar(self): #self.parent
Su implementación en un archivo Frame es la siguiente:
self.tiempo_ = tiempo(self) self.tiempo_.start()
Para detener su funcionamiento:
self.tiempo_.stop()
Referencias
[http://www.blog.Pythonlibrary.org/2010/05/22/wxPython-and-Threads/]
[http://091labs.com/wp-content/uploads/2011/11/python.png]
Posdata
Los Threads se deben de detener y eliminar correctamente para evitar seguir consumiendo los recursos de la PC en dado caso se esté desarrollando alguna aplicación en un nivel mas formal. En esta publicación no se encuentra dicha implementación.