Manejo de ComboBoxEntry (pygtk)

Arnau Sanchez arnau en ehas.org
Lun Dic 11 07:01:39 CET 2006


Hola Jesús,

> He creado un evento que cuando se pulse la tecla intro (conectando el
> key-press-event del entry del CBE) pues se agregue en la lista.
> 
> Pero me da este error:
> 
> comboentry.py:39: GtkWarning: gtk_combo_box_append_text: assertion
> `GTK_IS_LIST_STORE (combo_box->priv->model)' failed
>  self.cmbe.append_text(texto)

El assert te está avisando de que no has especificado un modelo para el 
ComboBoxEntry. En otras palabras, que no sabe qué tipo de datos quieres 
mostrar (en este caso, quieres un campo único tipo cadena).

 > self.cmbe.append_text(texto)

No deberías hacer eso, fíjate lo que dice la documentación:

http://www.pygtk.org/pygtk2reference/class-gtkcombobox.html#method-gtkcombobox--append-text

The append_text() method appends the string specified by text to the 
list of strings stored in the combo box gtk.ListStore. *Note that you 
can only use this method with combo boxes constructed with the 
gtk.combo_box_new_text() function.*

Así, sólo cuando obtienes el combo directamente puedes llamar a las 
funciones *_text:

combo = gtk.combo_box_entry_new_text()
combo.append_text(cadena)

Pero si, como en tu caso, ya tienes el objeto creado desde glade, le 
debes asignar el modelo a posteriori, y usar las funciones 
append/insert/remove sobre el modelo (ojo, los valores dentro de una 
lista), no sobre el combo:

#obtienes el objeto combo de glade
liststore = gtk.ListStore(str)
combo.set_model(liststore)
combo.set_text_column(0)
combo.append([cadena])

(Nota: algunas veces he probado a usar el append_text con combos de 
glade y *también* me ha funcionado. Pero como está explícitamente 
prohibido en la documentación oficial, mejor no arriesgarse)

Más información:

http://www.pygtk.org/pygtk2reference/class-gtkliststore.html
http://www.async.com.br/faq/pygtk/index.py?req=show&file=faq16.008.htp

> def key(self, widget, event):
>        if event.keyval == 65293:
>            print "Has pulsado intro"

Un apunte, sólo tendrías que explicitar valores constantes cuando sea 
estrictamente necesario (afecta a la legibilidad). Como los keyvals te 
los proporciona el propio gtk, es mejor que los uses:

     if event.keyval == gtk.keysyms.Return

La tabla está en el fichero "keysyms.py" del paquete pygtk. En las 
distros debian, por ejemplo, encontrarás las definiciones en este 
fichero: /usr/share/python-support/python-gtk2/gtk-2.0/gtk/keysyms.py

Pero en este caso concreto no te recomendaría usar "key-press-event", 
los widgets "entry" ya tienen la señal "activate", que se emite 
precisamente al apretar enter:

http://www.pygtk.org/pygtk2reference/class-gtkentry.html#signal-gtkentry--activate

Por mi experiencia en pygtk, me he dado cuenta que es muy útil saber 
utilizar los widgets directamente; que luego en tu proyecto usas glade, 
perfecto, pero ya curtido con el uso de los widgets de primera mano. 
Además, eso te permite sacarle más provecho a la consola interactiva que 
incluye el tutorial, muy útil para hacer pruebas:

http://www.pygtk.org/pygtk2tutorial/examples/pygtkconsole.py




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