Estou começando a escrever um programa com 'rapidamente'. Uma lista de idiomas desejados será uma de suas preferências. 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 no 'getter'
e no código acima?'setter'
'changed'
A abordagem parece fácil para widgets de entrada simples e similares, mas não sei como usá-la com listas.
Alternativamente, eu aceitaria qualquer outra maneira de lidar com listas como preferências, desde que o comprimento da lista não seja fixo.
Responder1
Isenção de responsabilidade: eu não sabia nada sobrerapidamenteaté eu ler sua postagem, ou sobre programação GUI em geral. Portanto, honestamente, não tenho por que tentar responder a esta pergunta :)
Dito isto,rapidamenteé um projeto legal. Examinei brevemente a fonte padrão e identifiquei as seguintes abordagens potenciais para adicionar uma preferência de estilo de lista apoiada por ListStore:
- 'Monkey-patch' obtém e define widget_methods em um widget TreeView de estoque (com modelo ListStore) conforme definido em data/ui/Preferences$PROJECTNAME$Dialog.ui com glade.
- Implemente
set_widget_from_preference
eset_preference
na subclasse de PreferencesDialog do projeto (a subclasse é Preferences$PROJECTNAME$Dialog) e faça algo diferente quandokey
ouwidget
seu widget TreeView for suportado por ListStore. - Escreva uma subclasse personalizada de gtk.TreeView com uma correspondênciawidget personalizado para glade.
Para testá-los, implementei todas essas três ideias – cada uma funcionou como pretendido, e AFAICT, de forma idêntica. No final, o terceiro (em particular) me pareceu o mais limpo e mais próximo das convenções utilizadas em todo o clichê, apesar de inicialmente esperar o contrário.
Aqui estão os passos que segui para o número três ...
Usando o glade via quickly design
(rapidamente 11.10, aliás) e seguindo vagamenteeste tutorial (parte 2), adicione um widget ScrolledWindow ao Preferences$PROJECTNAME$Dialog.ui, coloque um TreeView nele e nomeie o TreeView language_treeview
. Crie um novo modelo ListStore para o TreeView quando solicitado e nomeie-o como idioma_liststore, etc... eventualmente acabei com algo assim:
Em seguida, adicione um catálogo glade (data/ui/preferences_$PROJECTNAME$_treeview.xml) com o seguinte conteúdo:
<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>
Em seguida, edite Preferences$PROJECTNAME$Dialog.ui, adicionando ...
<!-- interface-requires preferences_$PROJECTNAME$_treeview 1.0 -->
... para o topo, sob a tag requer. E altere o atributo de classe 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 de um e dois, ficarei feliz em atendê-lo.
Editar:Para o leitor casual, substitua qualquer ocorrência de$PROJETONAME$com o nome real do seurapidamenteprojeto (conforme especificado em quickly create
).
AH!
Responder2
Eu não tentei 'rapidamente', mas com minha experiência em GTK eu usariaBotões do rádiopara lidar com a seleção do idioma.
Observar o toggled
evento junto com o button.get_active()
método deve ser suficiente para verificar o que o usuário selecionou.