Aplicación rápida con ListStore como preferencia

Aplicación rápida con ListStore como preferencia

Estoy empezando a escribir un programa con "rápidamente". Una lista de los idiomas deseados será una de sus preferencias. Ejemplo:

languages = ["en", "de"]

El código rápido (creado automáticamente) que maneja la parte de preferencia se ve así:

# Define your preferences dictionary in the __init__.main() function.
# The widget names in the PreferencesTestProjectDialog.ui
# file need to correspond to the keys in the preferences dictionary.
#
# Each preference also need to be defined in the 'widget_methods' map below
# to show up in the dialog itself.  Provide three bits of information:
#  1) The first entry is the method on the widget that grabs a value from the
#     widget.
#  2) The second entry is the method on the widget that sets the widgets value
#      from a stored preference.
#  3) The third entry is a signal the widget will send when the contents have
#     been changed by the user. The preferences dictionary is always up to
# date and will signal the rest of the application about these changes.
# The values will be saved to desktopcouch when the application closes.
#
# TODO: replace widget_methods with your own values


widget_methods = {
    'languages': ['getter', 'setter', 'changed'],
}

En la GUI, parece que el widget elegido en gtk para una lista es ListStore (que no es un widget, sino un modelo, pero está definido en el archivo Glade...). ¿Alguien puede decirme qué funcionaría para ListStore para 'getter'y 'setter'en 'changed'el código anterior?

El enfoque parece fácil para widgets de entrada simples y demás, pero no sé cómo usarlo con listas.

Alternativamente, por supuesto aceptaría cualquier otra forma de tratar las listas como preferencias, siempre que la longitud de la lista no sea fija.

Respuesta1

Descargo de responsabilidad: no sabía nada sobrerápidamentehasta que leí tu publicación, o sobre la programación gui en general. Por lo tanto, sinceramente, no tengo por qué intentar responder esta pregunta :)

Dicho eso,rápidamentees un proyecto genial. Escaneé brevemente la fuente repetitiva e identifiqué los siguientes enfoques potenciales para agregar una preferencia de estilo de lista respaldada por ListStore:

  1. 'Monkey-patch' obtiene y configura widget_methods en un widget TreeView estándar (con modelo ListStore) como se define en data/ui/Preferences$PROJECTNAME$Dialog.ui con glade.
  2. Implemente set_widget_from_preferencey set_preferenceen la subclase de PreferencesDialog del proyecto (la subclase es Preferences$PROJECTNAME$Dialog) y haga algo diferente cuando keyo widgetsea su widget TreeView respaldado por ListStore.
  3. Escriba una subclase personalizada de gtk.TreeView con una coincidenciawidget personalizado para glade.

Para probarlas, implementé estas tres ideas: cada una funcionó según lo previsto y AFAICT de manera idéntica. Al final, el tercero (en particular) me pareció el más limpio y más cercano a las convenciones utilizadas en todo el texto estándar, a pesar de que inicialmente esperaba lo contrario.


Estos son los pasos que seguí para el número tres...

Usando glade via quickly design(rápidamente 11.10, por cierto) y siguiendo librementeeste tutorial (parte 2), agregue un widget ScrolledWindow a Preferences$PROJECTNAME$Dialog.ui, suelte un TreeView y asígnele el nombre TreeView language_treeview. Cree un nuevo modelo ListStore para TreeView cuando se le solicite y asígnele el nombre language_liststore, etc. Finalmente terminé con algo como esto:

propiedades-claro

A continuación, agregue un catálogo de glade (data/ui/preferences_$PROJECTNAME$_treeview.xml) con el siguiente contenido:

<glade-catalog name="preferences_$PROJECTNAME$_treeview" domain="glade-3"
               depends="gtk+" version="1.0">
  <glade-widget-classes>
    <glade-widget-class title="$PROJECTNAME$ Preferences TreeView" name="Preferences$PROJECTNAME$TreeView"
                        generic-name="Preference$PROJECTNAME$TreeView" parent="GtkTreeView"
                        icon-name="widget-gtk-treeview"/>
  </glade-widget-classes>
</glade-catalog>

Luego, edite Preferencias$PROJECTNAME$Dialog.ui, agregando...

<!-- interface-requires preferences_$PROJECTNAME$_treeview 1.0 -->

... hasta la parte superior, debajo de la etiqueta requiere. Y cambie el atributo de clase de language_treeview a Preferencias$PROJECTNAME$TreeView, en preparación para un paso posterior.

Finalmente, agregue el siguiente elemento a la lista widget_methods en Preferencias$PROJECTNAME$Dialog.py

'language_treeview': ['get_languages', 'set_languages', 'button-release-event']

Y al final del mismo archivo (Preferencias$PROJECTNAME$Dialog.py), agregue

import gtk

ALL_LANGUAGES = [
  'en', 'uk', 'de', 'fr', # ... much longer list
]

class Preferences$PROJECTNAME$TreeView(gtk.TreeView):
    __gtype_name__ = "Preferences$PROJECTNAME$TreeView"

    def __init__(self, *args):
        super(Preferences$PROJECTNAME$TreeView, self).__init__(*args)
        self.get_selection().set_mode(gtk.SELECTION_MULTIPLE)

    # loads the liststore with all languages, 
    # selecting/highlighting in the treeview those 
    # already retrieved from previously saved preferences
    def set_languages(self, preferred_languages):
        model = self.get_model()
        for row, lang in enumerate(ALL_LANGUAGES):
            model.append([lang])
            if lang in preferred_languages:
                self.get_selection().select_iter(model.get_iter(row))

    # collects only the selected languages in the treeview
    # to save in the preferences database
    def get_languages(self):
        model, rows = self.get_selection().get_selected_rows()
        result = [model.get_value(model.get_iter(row), 0) for row in rows]
        return result

Si está interesado en ver mis intentos para uno y dos, estaré encantado de hacerlo.

Editar:Para el lector ocasional, reemplace cualquier aparición de$NOMBRE DEL PROYECTO$con el nombre real de turápidamenteproyecto (como se especifica en quickly create).

¡HH!

Respuesta2

Yo mismo no lo he probado 'rápidamente', pero con mi experiencia en GTK usaríaBotones de radiopara manejar la selección de idioma.

Ver el toggledevento junto con el button.get_active()método debería ser suficiente para verificar lo que el usuario ha seleccionado.

información relacionada