liststore - python gtk3 glade
¿Ha cambiado el subprocesamiento en GTK con Python en la introspección de PyGObject? (1)
Estoy en el proceso de convertir un programa de PyGTK a la introspección PyGObject por primera vez y he golpeado un obstáculo con subprocesos. Tengo un proceso que toma algún tiempo en completarse, así que abro un diálogo con una barra de progreso y uso un hilo para hacer el proceso y actualizar la barra de progreso. Esto funcionó bien con PyGTK, pero después de convertir a PyGObject, obtengo todas las rarezas de subprocesos incorrectas habituales: el programa se cuelga, pero parece que se bloquea en diferentes partes del proceso, etc. no averiguar qué.
Este es un ejemplo simple de la barra de progreso de PyGTK: http://aruiz.typepad.com/siliconisland/2006/04/threads_on_pygt.html Tal como se presenta en esa página, el código funciona. Lo he convertido a la introspección PyGObject y tengo los mismos problemas que en mi programa: se bloquea, no actualiza correctamente la barra de progreso, etc.
import threading
import random, time
from gi.repository import Gtk, Gdk
#Initializing the gtk''s thread engine
Gdk.threads_init()
class FractionSetter(threading.Thread):
"""This class sets the fraction of the progressbar"""
#Thread event, stops the thread if it is set.
stopthread = threading.Event()
def run(self):
"""Run method, this is the code that runs while thread is alive."""
#Importing the progressbar widget from the global scope
global progressbar
#While the stopthread event isn''t setted, the thread keeps going on
while not self.stopthread.isSet() :
# Acquiring the gtk global mutex
Gdk.threads_enter()
#Setting a random value for the fraction
progressbar.set_fraction(random.random())
# Releasing the gtk global mutex
Gdk.threads_leave()
#Delaying 100ms until the next iteration
time.sleep(0.1)
def stop(self):
"""Stop method, sets the event to terminate the thread''s main loop"""
self.stopthread.set()
def main_quit(obj):
"""main_quit function, it stops the thread and the gtk''s main loop"""
#Importing the fs object from the global scope
global fs
#Stopping the thread and the gtk''s main loop
fs.stop()
Gtk.main_quit()
#Gui bootstrap: window and progressbar
window = Gtk.Window()
progressbar = Gtk.ProgressBar()
window.add(progressbar)
window.show_all()
#Connecting the ''destroy'' event to the main_quit function
window.connect(''destroy'', main_quit)
#Creating and starting the thread
fs = FractionSetter()
fs.start()
Gtk.main()
En la documentación de las capacidades de subprocesos de Gdk, se destaca que primero debe ejecutar g_thread_init (NULL) antes de ejecutar gdk_threads_init (). Pero para ejecutar eso, necesitas vincular algunas bibliotecas adicionales. Si intento importar GLib a través de la introspección y luego intento ejecutar GLib.thread_init (), aparece el siguiente error:
>>> from gi.repository import GLib
>>> GLib.thread_init(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
glib.GError: Could not locate g_thread_init: `g_thread_init'': /usr/lib/libglib-2.0.so.0: undefined symbol: g_thread_init
Supongo que esto se debe a que las bibliotecas de subprocesos adicionales no estaban vinculadas. Si esta es la causa de mis problemas de subprocesos, ¿cómo puedo trabajar con GLib como si esas bibliotecas estuvieran vinculadas?
Logré responder a mi propia pregunta hojeando algunos programas Gnome escritos en Python (Gnome Sudoku, en este caso, que en realidad me ha ayudado un par de veces).
El truco es que debes llamar a GObject.threads_init()
al comienzo de tu código, no a GLib.thread_init()
como lo indica la documentación de C.