Rapidamente aplicação com ListStore como preferência

10

Estou começando a escrever um programa com "rapidez". Uma lista de idiomas desejados será um prefereces. Exemplo:

languages = ["en", "de"]

O código rápido (criado automaticamente) que lida com a parte de preferência é assim:

# 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'],
}

Na GUI, parece que o widget escolhido em gtk para uma lista é um ListStore (que não é um widget, mas um modelo, mas é definido no arquivo Glade ...). Alguém pode me dizer o que funcionaria para um ListStore para o 'getter' , 'setter' e 'changed' no código acima?

A abordagem parece fácil para simples widgets de entrada e coisas assim, mas eu não sei como usá-la com listas.

Como alternativa, é claro que aceitarei qualquer outra maneira de lidar com listas como preferências, desde que o tamanho da lista não seja fixo.

    
por xubuntix 11.10.2011 / 15:37

2 respostas

2

Disclaimer: Eu não sabia nada sobre rapidamente até que eu li o seu post, ou sobre programação de gui em geral para esse assunto. Portanto, sinceramente, não tenho nenhum negócio tentando responder a essa pergunta:)

Dito isso, rapidamente é um projeto interessante. Examinei rapidamente a fonte clichê e identifiquei as seguintes possíveis abordagens para adicionar uma preferência de estilo de lista com suporte do ListStore:

  1. 'Monkey-patch' obtenha e defina widget_methods em um TreeView padrão widget (com modelo ListStore) como definido em dados / ui / Preferences $ PROJECTNAME $ Dialog.ui com glade.
  2. Implemente set_widget_from_preference e set_preference no subclasse do projeto de PreferencesDialog (a subclasse é Preferences $ PROJECTNAME $ Dialog), e fazer algo diferente quando key ou widget é seu widget TreeView com suporte a ListStore.
  3. Escreva uma subclasse personalizada de gtk.TreeView com um widget personalizado para o glade correspondente .

Para testá-los, implementei todas essas três ideias - cada uma funcionou como pretendido e AFAICT, identicamente. No final, o terceiro (em particular) parecia o mais limpo para mim, e mais próximo das convenções usadas em todo o clichê, apesar de inicialmente esperar o oposto.

Aqui estão os passos que segui para o número três ...

Usando o glade via quickly design (rapidamente 11.10, btw) e seguindo frouxamente este tutorial (parte 2) , adicione um widget ScrolledWindow ao Preferences $ PROJECTNAME $ Dialog.ui, solte um TreeView nele, nomeie o TreeView language_treeview . Crie um novo modelo ListStore para o TreeView quando solicitado e nomeie-o language_liststore, etc ... eventualmente acabei com algo parecido com isto:

Emseguida,adicioneumcatálogoglade(data/ui/preferences_$PROJECTNAME$_treeview.xml)comoseguinteconteúdo:

<glade-catalogname="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>

Em seguida, edite as Preferências $ PROJECTNAME $ Dialog.ui, adicionando ...

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

... para o topo, sob a tag requer. E mude o atributo class de language_treeview para Preferences $ PROJECTNAME $ TreeView, em preparação para uma etapa posterior.

Por fim, adicione o seguinte elemento à lista widget_methods em Preferences $ PROJECTNAME $ Dialog.py

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

E no final do mesmo arquivo (Preferences $ PROJECTNAME $ Dialog.py), adicione

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

Se você estiver interessado em ver minhas tentativas para um e dois, fico feliz em ajudar.

Editar: Para o leitor casual, substitua qualquer ocorrência de $ PROJECTNAME $ pelo nome real do seu rápido projeto (conforme especificado no quickly create ).

HTH!

    
por mwalsh 20.10.2011 / 06:13
0

Eu não tentei "rapidamente" a mim mesmo, mas com a minha experiência em GTK eu usaria Botões de opção para lidar com a seleção de idiomas.

A observação do evento toggled juntamente com o método button.get_active() deve ser suficiente para verificar o que o usuário selecionou.

    
por Alexandre 16.10.2011 / 23:15