Что такое «хорошая практика» для написания приложения Python GTK+?

В настоящее время я пишу приложение PyGTK, и мне нужен совет о том, как лучше всего структурировать мое приложение. В основном приложение считывает конкретную спецификацию файла и представляет ее в графическом интерфейсе для редактирования.

В настоящее время у меня есть parser.py, который обрабатывает все низкоуровневые операции ввода-вывода и анализ файла. Я показываю содержимое файла в виде дерева, что означает, что мне нужно использовать хранилище дерева в качестве типа данных.

Проблема, с которой я столкнулся, заключается в том, что я придумал только два решения этой проблемы. Во-первых, мой синтаксический анализатор может построить хранилище дерева и передать его моему классу пользовательского интерфейса. Это требует, чтобы мой синтаксический анализатор зависел от pygtk, и сводит к минимуму потенциальное повторное использование класса. Вторым будет сохранение ссылки на мой класс пользовательского интерфейса в синтаксическом анализаторе, что также потенциально ограничит повторное использование моего класса синтаксического анализатора в качестве отдельной библиотеки.

Чтобы сжать мой вопрос в одну короткую строчку: есть ли способ достичь моих целей более питоническим или ООП-дружественным способом?

Если мой код поможет любому, кто пытается ответить на мой вопрос: https://code.launchpad.net/~blainepace/nbtparser/trunk

Другие питонические предложения приветствуются, это моя первая программа на Python, и я могу застрять в стиле мышления, более похожем на C++. Я планирую рефакторинг многих из них.


person sensae    schedule 09.09.2010    source источник


Ответы (1)


Вы должны взглянуть на учебник "Sub- классификация GObject в Python". Это происходит через использование системы типов GObject для создания сигналов и свойств, которые позволяют вам моделировать базовое поведение таким образом, чтобы его можно было легко интегрировать с типичной семантикой PyGTK (подключение к сигналам, ожидание уведомлений о свойствах и т. д.).

И ваш парсер, и пользовательский интерфейс должны иметь только свойства и сигналы для подключения. Затем у вас есть третий класс, который соединяет эти сигналы и обратные вызовы и запускает основной цикл в блоке if __name__ == __main__.

Обычно мои выглядят примерно так:

class MyApp(gtk.Window):

    def __init__(self, parser, ui):
        gtk.Window.__init__(self)
        parser.connect("some-signal", ui.update_this)
        parser.connect("some-other-signal", ui.update_that, extra_params)
        ui.connect("refresh-clicked", parser.reparse_file)
        self.add(ui)

... а затем в вашем основном скрипте:

parser = parser.Parser(...)
ui = view.ParseView(...)
app = MyApp(parser, ui)

app.show_all()

gtk.main()

Конечно, это часто отличается в зависимости от, например. я использую Glade? Должен ли я создавать подклассы виджетов для основного приложения или обертывать их? и т. д.

Самое замечательное в этом то, что вы можете написать, скажем, тестовый синтаксический анализатор, который ничего не делает, кроме как возвращает предварительно запрограммированные ответы или использует известный тестовый файл. Заменить его так же просто, как изменить одну строку выше:

parser = parser.DummyParser(...)
person detly    schedule 09.09.2010