glade

Lorenzo Gil Sanchez lgs en sicem.biz
Jue Ago 21 14:18:02 CEST 2003


Hablando con James Henstridge por IRC sobre el signal_autoconnect me ha
comentado lo siguiente:

<jamesh> lgs: it looks for handlers by calling __getitem__ on the object
first, then __getattr__

Es decir, cuando haces self.widgets.signal_autoconnect(self) ese metodo
llama a self.__getitem__ buscando los callbacks y si no los encuentra es
cuando llama a __getattr__. La cosa es que como tu __getitem__ esta
llamando a gtk.glade.XML.get_widget('nombre_widget') ahi es donde se lia
el tema.

En cualquier caso, no me parece acertado usar el __getitem__ si el unico
beneficio es que escribes esto

app = Application()
app['button1].loquesea()

en lugar de

app = Application()
app.widgets.get_widget('button1').loquesea()

Un saludo

Lorenzo Gil

El jue, 21-08-2003 a las 12:48, dvilla en gmx.net escribió:
> Hola:
> 
> Cuando ponía el self me daba este error:
> 
> ** (app.py:1714): WARNING **: handler for `on_button1_clicked' not callable or a
> tuple
> 
> Como me estaba volviendo loco, he empezado a meter cachos de mi programa en el
> iface.py que si que funciona hasta que he encontrado el problema. Era culpa de
> un método__getitem__[1] que tengo definido para extraer widgets del árbol
> 'self.widgets'. Por alguna razón que desconozco este método da problemas a
> signal_autoconnect. Alguna idea?
> 
> Saludos y muchas gracias.
> 
> [1] http://www.russnelson.com/pyglade-tutorial/pyglade-tutorial
> 
> El 21 Aug 2003 11:35:12 +0200
> Lorenzo Gil Sanchez <lgs en sicem.biz> escribió:
> 
> > No se exactamente lo que hace el autoconnect intermante pero a mi me
> > funciona con el self, lo has probado? Acabo de volver a probarlo esta
> > vez con tu archivo de glade y funciona. Cunado pulso en el boton esto es
> > la salida que me da:
> > 
> > [lgs en i8100 lgs]$ python iface.py
> > hola
> > <__main__.Application instance at 0x824172c>
> > <gtk.Button object (GtkButton) at 0x82aec14>
> > <GdkEvent at 0x82b23c8>
> > 
> > Este es el codigo:
> > 
> > import pygtk
> > pygtk.require("2.0")
> >   
> > import gtk, gtk.glade
> >   
> > class Application:
> >     def __init__(self):
> >         self.widgets = gtk.glade.XML('iface.glade')
> >         self.widgets.signal_autoconnect(self) # <-  OJO al self
> >   
> >     def on_button1_clicked(self, button, event):
> >         print self
> >         print button
> >         print event
> > 
> > app = Application()
> > gtk.main()
> > 
> > 
> > Te lo adjunto por si quieres probarlo tu.
> > 
> > Lorenzo
> > 
> > 
> > El jue, 21-08-2003 a las 11:12, dvilla en gmx.net escribió:
> > > Hola:
> > > 
> > > Te mando el .glade pero es muy tonto, es una ventana con un botón. 
> > > Lo de pasar la referencia al objeto no parece funcionar. Se supone que el
> > > autoconnect sólo admite diccionarios, no?. Autoconnect compara las cadenas
> > > definidas en el diccionario con los handlers del .glade.
> > > self.__class__.__dict__ es lo mismo que Application.__dict__ pero esos
> > > diccionarios tienen referencias a los métodos como si fuesen estáticos, es
> > > decir, no se especifica ninguna referencia a ningún objeto.
> > > 
> > > 
> > > El 21 Aug 2003 10:18:05 +0200
> > > Lorenzo Gil Sanchez <lgs en sicem.biz> escribió:
> > > 
> > > > A ver si ahora te he entendido bien:
> > > > 
> > > > import pygtk
> > > > pygtk.require("2.0")
> > > >  
> > > > import gtk, gtk.glade
> > > >  
> > > > class Application:
> > > >     def __init__(self):
> > > >         self.widgets = gtk.glade.XML('ejemplo.glade')
> > > >         self.widgets.signal_autoconnect(self) # <-  OJO al self
> > > >  
> > > >     def on_button1_clicked(self, *args):
> > > >         print 'hola'
> > > >         print self, args
> > > > 
> > > > app = Application()
> > > > gtk.main()
> > > > 
> > > > 
> > > > creo que eso es lo que quieres
> > > > 
> > > > Un saludo
> > > > 
> > > > Lorenzo
> > > > 
> > > > NOTA: otra vez, mandame el archivo de glade please.
> > > > 
> > > > El mié, 20-08-2003 a las 22:20, dvilla en gmx.net escribió:
> > > > > Hola:
> > > > > 
> > > > > Soy yo el que no se ha explicado bien. Necesito que el callback sea un
> > > > > método(pero no un método clase), es decir, que no me sirve un método
> > > > > estático. Esto es así porque dentro del método tengo que utilzar
> > > > > atributos del objeto actual.
> > > > > 
> > > > > Prueba esto:
> > > > > 
> > > > > import pygtk
> > > > > pygtk.require("2.0")
> > > > >  
> > > > > import gtk, gtk.glade
> > > > >  
> > > > > class Application:
> > > > >     def __init__(self):
> > > > >         self.widgets = gtk.glade.XML(gladefile)
> > > > >         self.widgets.signal_autoconnect(Application.__dict__)
> > > > >  
> > > > >     def on_button1_clicked(self, *args):
> > > > >         print 'hola'
> > > > > 	print self, args
> > > > > 
> > > > > app = Application()
> > > > > gtk.main()
> > > > > 
> > > > > Según te he entendido, tu dices que en 'self' viene la referencia a
> > > > > objeto y en'args' el GtkWidget, pues no. Prueba y verás que en 'self'
> > > > > viene el GtkWidget y en 'args' un GdkEvent.
> > > > > 
> > > > > Si haces un diccionario a mano, es decir:
> > > > > 
> > > > > import pygtk
> > > > > pygtk.require("2.0")
> > > > >  
> > > > > import gtk, gtk.glade
> > > > >  
> > > > > class Application:
> > > > >     def __init__(self):
> > > > >         self.widgets = gtk.glade.XML(gladefile)
> > > > > 	callbacks = {"on_button1_clicked": self.on_button1_clicked}
> > > > >         self.widgets.signal_autoconnect(callbacks)
> > > > >  
> > > > >     def on_button1_clicked(self, *args):
> > > > >         print 'hola'
> > > > > 	print self, args
> > > > > 
> > > > > app = Application()
> > > > > gtk.main()
> > > > > 
> > > > > Entonces si funciona bien: en 'self' viene la referencia al objeto y en
> > > > > 'args' vienen el GtkWidget y el GdkEvent. Pero yo quiero saber si se
> > > > > puede hacer con el signal_autoconnect.
> > > > > 
> > > > > Saludos.
> > > > > 
> > > > > 
> > > > > El Wed, 20 Aug 2003 21:26:33 +0200
> > > > > Lorenzo Gil Sanchez <lgs en sicem.biz> escribió:
> > > > > 
> > > > > > El mi_, 20-08-2003 a las 20:31, dvilla en gmx.net escribi_:
> > > > > > Hola:
> > > > > > > 
> > > > > > > Alguien sabe si el signal_autoconnect() de libglade se puede
> > > > > > > utilizar de modo que los callbacks sean m_todos no-de-clase. Este
> > > > > > > ejemplo me funciona:
> > > > > > > 
> > > > > > > import pygtk
> > > > > > > pygtk.require("2.0")
> > > > > > > 
> > > > > > > import gtk, gtk.glade
> > > > > > > 
> > > > > > > class Application:
> > > > > > >     def __init__(self):
> > > > > > >         self.widgets = gtk.glade.XML(gladefile)
> > > > > > >         self.widgets.signal_autoconnect(Application.__dict__)
> > > > > > > 
> > > > > > >     def on_button1_clicked(widget, event):
> > > > > > >         print 'hola'
> > > > > > > 
> > > > > > > 
> > > > > > > Pero si on_button1_clicked() no es un m_todo de clase, es decir:
> > > > > > > 
> > > > > > >     def on_button1_clicked(self, widget, event):
> > > > > > >         print 'hola'
> > > > > > > 
> > > > > > > Entonces el autoconnect no se entera y llama a este m_todo con 2
> > > > > > > argumentos en lugar de tres. Alguien sabe si se puede hacer?
> > > > > > > 
> > > > > > > Veamos, tienes un fallo en lo siguiente: El callback para la senial
> > > > > > > 'clicked' [1] es el siguiente
> > > > > > 
> > > > > > def callback(button):
> > > > > >     pass
> > > > > > 
> > > > > > 
> > > > > > o si es un metodo de clase
> > > > > > 
> > > > > > 
> > > > > > def callback(self, button):
> > > > > >    pass
> > > > > > 
> > > > > > 
> > > > > > Por eso en tu ejemplo te funciona el metodo para una clase porque
> > > > > > tienes la suerte de estar dandole 2 argumentos:
> > > > > > 
> > > > > > def on_button1_clicked(widget, event):
> > > > > >      print hola
> > > > > > 
> > > > > > si haces esto
> > > > > > 
> > > > > > def on_button1_clicked(widget, event):
> > > > > >      print widget, event
> > > > > > 
> > > > > > probablemente te des cuenta que tu argumento widget es en realidad de
> > > > > > tipo Application y tu argumento event es de tipo gtk.Button
> > > > > > 
> > > > > > Despues de todo este rollo te respondo a tu pregunta:
> > > > > > 
> > > > > > import pygtk
> > > > > > pygtk.require('2.0')
> > > > > > import gtk
> > > > > > import gtk.glade
> > > > > > 
> > > > > > def on_button1_clicked(button):
> > > > > >      print 'hola'
> > > > > > 
> > > > > > widgets = gtk.glade.XML(gladefile)
> > > > > > widgets.autoconnect(locals())
> > > > > > 
> > > > > > No se si me he explicado bien
> > > > > > 
> > > > > > Lorenzo Gil
> > > > > > 
> > > > > > [1]
> > > > > > http://www.moeraki.com/pygtkreference/pygtk2reference/class-gtkbutton.html#signal-gtkbutton--clicked
> > > > > > 
> > > > > > 
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> 
> 




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