Быстро приложение с ListStore в качестве предпочтения


10

Я начинаю писать программу с «быстро». Список желаемых языков будет одним из предпочтений. Пример:

languages = ["en", "de"]

(Автоматически созданный) быстрый код, который обрабатывает предпочтительную часть, выглядит следующим образом:

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

В графическом интерфейсе кажется, что выбранный виджет в gtk для списка - это ListStore (это не виджет, а модель, но он определен в файле Glade ...). Может кто-нибудь сказать мне, что будет работать для ListStore для 'getter', 'setter'и 'changed'в коде выше?

Подход выглядит простым для простых виджетов ввода и тому подобного, но я не знаю, как использовать его со списками.

В качестве альтернативы я бы, конечно, принял любой другой способ обработки списков в качестве предпочтений, при условии, что длина списка не является фиксированной.


Не ответ на вопрос, но зачем вашему приложению переключать языки? Разве он не может просто использовать gettext и заданную пользователем локаль для определения языка? Это стандартный способ работы с переводами приложения: оно будет работать автоматически и для вас будет гораздо меньше.
Дэвид Планелла

@DavidPlnella: хороший вопрос. Это не переключает языки. Приложение просматривает телевизионные эпизоды в базе данных. Поскольку многие люди говорят более чем на одном языке, эпизоды на всех них могут быть найдены. Пример: я смотрю немецкие и английские телевизионные эпизоды.
xubuntix

Ответы:


2

Отказ от ответственности: я ничего не знал о быстрой, пока я не прочитал ваш пост, или о графическом программировании в целом в этом отношении. Поэтому я, честно говоря, не имею никакого дела, пытаясь ответить на этот вопрос :)

Тем не менее, быстро это аккуратный проект. Я кратко просканировал исходный шаблон и определил следующие потенциальные подходы для добавления предпочтений в стиле списка в виде списка:

  1. 'Monkey-patch' получает и устанавливает виджет_методы на стандартный виджет TreeView (с моделью ListStore), как это определено в data / ui / Preferences $ PROJECTNAME $ Dialog.ui с полянкой.
  2. Реализовать set_widget_from_preferenceи set_preferenceв подклассе проекта из PreferencesDialog (подкласс является Preferences $ Projectname $ Dialog), и сделать что - то другое , когда keyили widgetваша ListStore поддерживается TreeView виджет.
  3. Напишите пользовательский подкласс gtk.TreeView с соответствующим пользовательским виджетом для поляны .

Чтобы проверить их, я реализовал все три эти идеи - каждая работала так, как задумывалось, и AFAICT - одинаково. В конце концов, третий (в частности) показался мне наиболее чистым и ближе к обычаям, используемым во всем шаблоне, несмотря на то, что изначально ожидал обратного.


Вот шаги, которые я следовал за номером три ...

Используя glade через quickly design(быстро 11.10, кстати) и неукоснительно следуя этому руководству (часть 2) , добавьте виджет ScrolledWindow в Preferences $ PROJECTNAME $ Dialog.ui, поместите в него TreeView, назовите TreeView language_treeview. При появлении запроса создайте новую модель ListStore для TreeView и назовите ее language_liststore и т. Д. ... в конце концов я получил нечто подобное:

поляна-свойство

Затем добавьте каталог glade (data / ui / preferences_ $ PROJECTNAME $ _treeview.xml) со следующим содержимым:

<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>

Затем отредактируйте Настройки $ PROJECTNAME $ Dialog.ui, добавив ...

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

... наверх, под тегом require. И измените атрибут класса language_treeview на Preferences $ PROJECTNAME $ TreeView, чтобы подготовиться к следующему шагу.

Наконец, добавьте следующий элемент в список widget_methods в Предпочтения $ PROJECTNAME $ Dialog.py

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

И в конце того же файла (Предпочтения $ PROJECTNAME $ Dialog.py) добавьте

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

Если вы заинтересованы в том, чтобы увидеть мои попытки на один и два, я с радостью вам обязуюсь.

Редактировать: для случайного читателя замените любое вхождение $ PROJECTNAME $ на фактическое имя вашего быстрого проекта (как указано в quickly create).

НТН!


Это работает очень хорошо и кажется вполне понятным, поэтому другие две попытки не нужны, но еще раз спасибо за их попытку ... Поскольку ваш ответ очень длинный, но все еще ясный, вы можете расширить его до полного урока здесь: developer.ubuntu.com/resources/tutorials/all В любом случае: еще раз спасибо!
xubuntix

@xubuntix Это интересная идея, я рассмотрю ее. Спасибо за ссылку и репутацию!
mwalsh

0

Я не пробовал «быстро» сам, но с моим опытом работы с GTK я бы использовал радио-кнопки для выбора языка.

Наблюдения за toggledсобытием вместе с button.get_active()методом должно быть достаточно, чтобы проверить, что выбрал пользователь.


Следуя вашему предложению, я снова посмотрел на кнопки радио, но это кажется не идеальным: поскольку список возможных языков намного длиннее, чем можно было бы дать с помощью кнопок радио, единственной альтернативой было бы наличие отдельного виджета, добавляющего дополнительные кнопки. и все радиокнопки всегда активны. Это кажется не очень хорошим.
xubuntix

Убедитесь, что вы используете радио группы правильно. Также toggledсобытие можно использовать как для выбранных, так и для невыбранных кнопок, поэтому этого должно быть достаточно.
Александр

Я имел в виду, что наличие 200 переключателей не является хорошим пользовательским интерфейсом. Что мне нужно, это способ сохранить список, где элементы могут быть добавлены и удалены по требованию.
xubuntix
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.