¿Cómo actualizo / redibujo un GTK Widget (GTKLabel) internamente sin un evento de pulsación de tecla usando python?

Tengo un código a continuación que intenta actualizar un elemento de etiqueta GTK. Estoy incluyendo dos archivos: el archivo ui y el archivo py.

Archivo de interfaz de usuario:

  320 240 True GDK_KEY_PRESS_MASK Simple False center-always 320 240 False center   320 240 True   320 40 True 0 l1   43       

Archivo de Python

 import os from time import sleep as wait import gtk as gtk import gtk.glade as glade import gobject class Application(object): def __init__ (self): self.glade = glade.XML("simple.ui") self.setup_ui() def setup_ui (self): self.window = self.glade.get_widget("ApplicationFrame") self.l1 = self.glade.get_widget("l1") self.names = {'l1' : self.l1} self.all = [self.l1] gobject.timeout_add(1000,self.display_me) gobject.timeout_add(100,self.do_something_that_takes_a_while) self.window.add_events(gtk.gdk.KEY_PRESS_MASK) self.window.connect("key-press-event", self.handler) self.window.connect("delete_event", self.delete_event) self.window.connect("destroy", self.destroy) self.window.show() def get_signal (self,widget,event): keyname = gtk.gdk.keyval_name(event.keyval) ctrl = event.state & gtk.gdk.CONTROL_MASK alt = event.state & gtk.gdk.MOD1_MASK shift = event.state & gtk.gdk.SHIFT_MASK name = [] if ctrl and keyname not in ["Control_L","Control_R"]: name.append("CTRL") if alt and keyname not in ["Alt_L","Alt_R"]: name.append("ALT") if shift and keyname not in ["Shift_L","Shift_R"]: name.append("SHIFT") name.append(keyname) name = "+".join(name) return name def handler (self,widget,event): name = self.get_signal(widget,event) if name.lower() in ['ctrl+x','ctrl+c','alt+q']: self.destroy() def main(self): gtk.main() def delete_event (self,widget=None,event=None,data=None): return False def destroy (self,widget=None,data=None): gtk.main_quit() def get (self,item): if isinstance(item, str): if item in self.names: item = self.names[item] retval = None if hasattr(item,"text"): retval = item.text() elif hasattr(item,"get_label"): retval = item.get_label() return retval def set (self,item,text='',font=None): print 'Setting...' if isinstance(item, str): if item in self.names: item = self.names[item] retval = None if font == None and hasattr(self,"page") and hasattr(self.page,"NORMAL_FONT"): font = self.page.NORMAL_FONT if hasattr(item,"setText"): retval = item.setText(text) elif font == None: if hasattr(item,'set_text'): retval = item.set_text(text) elif hasattr(item,"set_label"): retval = item.set_label(text) if hasattr(item,"modify_font") and font != None: item.modify_font(font) item.queue_draw() self.try_to_update(item) print 'done' return retval def try_to_update (self,item): """ do something here to update the visual screen???? """ print str(self) def do_something_that_takes_a_while (self): timeout = 15 while timeout != 0: self.set('l1','%s' % timeout) wait(1) timeout -= 1 print timeout return 1 def clean (self): if item != None: self.set(item,empty_text) else: if hasattr(self,'all'): for item in self.all: self.set(item) def display_me (self): print str(self) return True def __str__ (self): space = 25 value = '%'+str(space)+'s' lines = ['\n','-'*79] if hasattr(self,'all'): line = [] for obj in self.all: obj_value = self.get(obj) line.append(value % obj_value if obj_value != None else '') #line.append(value % ' ') lines.append(''.join(line)) lines.append('-'*79) return '\n'.join(lines) if __name__ == "__main__": from time import sleep as wait SEC = 1 app = Application() app.main() 

Esto debería ser simple, pero me estoy perdiendo por completo lo que estoy haciendo mal. El elemento l1 no se actualiza correctamente. Creo que el código dentro de try_to_update es donde necesito actualizar la interfaz de usuario, pero no entiendo a qué función debo llamar. ¿Puede ayudarme alguien, por favor?

¡Gracias por adelantado!

Querrás usar la función queue_draw del Widget:

El método queue_draw_area () invalida el área rectangular del widget (…) llamando al método gtk.gdk.Window.invalidate_rect() en la ventana del widget y todas sus ventanas secundarias.

Pero, como ya está haciendo eso en su método de set , mi conjetura es que la

 if hasattr(item,'show') 

check evita que el ítem se actualice. Otra comprobación es llamar a la función queue_draw en toda la ventana y ver si eso actualiza las cosas.

Alternativamente, fuerce los eventos que están en cola para ser procesados ​​de la siguiente manera:

 while gtk.events_pending(): gtk.main_iteration_do(True) 

Una cosa que sucede en el código es que mientras se ejecuta do_something_that_takes_a_while , no se procesan eventos. Una forma de resolverlo es forzar el procesamiento de eventos en algún punto dentro de ese método:

 --- code.py 2011-12-05 10:32:53.000000000 +0100 +++ code.py.bak 2011-12-05 10:27:22.000000000 +0100 @@ -95,8 +95,6 @@ timeout = 15 while timeout != 0: self.set('l1','%s' % timeout) - while gtk.events_pending(): - gtk.main_iteration() wait(1) timeout -= 1 print timeout