Как работать с несколькими распространенными пользовательскими интерфейсами?

Я работаю над приложением Python, которое работает на двух разных платформах, а именно на обычном настольном Linux и Maemo 4. Мы используем PyGTK на обеих платформах, но на Maemo есть несколько небольших настроек, чтобы он выглядел красиво, которые реализованы следующим образом:

if util.platform.MAEMO:
    # do something fancy for maemo
else:
    # regular pygtk

Существует примерно 15 таких операторов if, необходимых для того, чтобы пользовательский интерфейс выглядел и работал хорошо на Maemo 4.

Это было очень управляемо за все это время. Проблема в том, что некоторое время назад была выпущена новая версия Maemo (5, она же fremantle), и она имеет некоторые большие отличия от Maemo 4. Я не хочу добавлять кучу проверок по всему коду графического интерфейса, чтобы заставить все 3 платформы хорошо работать с одной и той же кодовой базой, потому что это приведет к путанице. Я также не хочу создавать копию исходного кода графического интерфейса для каждой платформы и просто модифицировать его для конкретной платформы (я хотел бы повторно использовать как можно больше кода).

Итак, как можно создать слегка разные пользовательские интерфейсы для разных платформ, основанные на одном и том же основном коде пользовательского интерфейса? Я не думаю, что это вопрос, специфичный для Python или Maemo, я просто хотел бы знать, как это делается.


person nikosapi    schedule 07.01.2010    source источник
comment
Какой тип кода различается между платформами: обратные вызовы, используемые виджеты, способ расположения виджетов (т. е. в разных контейнерах или в разном порядке) или просто определенные специфичные для платформы свойства виджетов?   -  person LeafStorm    schedule 07.01.2010
comment
Извините, я забыл это. Это все вышеперечисленное. В основе на всех платформах лежит PyGTK, затем в Maemo 4 есть кое-что из hildon (виджеты, специфичные для Maemo, которые имеют разные имена/сигналы/и т. д.), а затем в Maemo 5 есть еще более причудливые hildon-штучки и другие некоторые другие виджеты, которые делают приложение более удобным. Кроме того, в версии Maemo 5 мы хотим иметь поддержку ротации, которая требует перестановки виджетов на лету.   -  person nikosapi    schedule 07.01.2010


Ответы (3)


Вы можете намотать многое из этого на фабрике:

def createSpec():
  if util.platform.MAEMO: return Maemo4Spec()
  elif util.platform.MAEMO5: return Maemo5Spec()
  return StandardPyGTKSpec()

Затем где-то в начале кода вы просто вызываете эту фабрику:

 spec = createSpec()

Теперь везде, где у вас были условия, вы просто вызываете нужную функцию:

 spec.drawComboBox()

Пока drawComboBox() обрабатывает что-то конкретное для платформы, вы должны быть в хорошей форме.

person Kaleb Pederson    schedule 07.01.2010

Вы можете изолировать специфичные для платформы вещи, которые вам нужно делать, в небольшие функции с согласованными именами внутри platform модуля, создать правильное имя функции, используя платформу, на которой вы работаете, а затем getattr правильное и вызвать его. Шаблон if/else тогда исчезнет.

person Noufal Ibrahim    schedule 07.01.2010

Я сделал отдельный модуль для обработки всей моей специализации между обычным Linux, Maemo 4.1 и Maemo 5. Он определяет, какие функции доступны, и позволяет программе плавно деградировать.

Например

 def _fremantle_hildonize_window(app, window):
         oldWindow = window
         newWindow = hildon.StackableWindow()
         oldWindow.get_child().reparent(newWindow)
         app.add_window(newWindow)
         return newWindow


 def _hildon_hildonize_window(app, window):
         oldWindow = window
         newWindow = hildon.Window()
         oldWindow.get_child().reparent(newWindow)
         app.add_window(newWindow)
         return newWindow


 def _null_hildonize_window(app, window):
         return window


 try:
         hildon.StackableWindow
         hildonize_window = _fremantle_hildonize_window
 except AttributeError:
         try:
                 hildon.Window
                 hildonize_window = _hildon_hildonize_window
         except AttributeError:
                 hildonize_window = _null_hildonize_window

Дополнительные сведения см. в исходном коде Dialcentral, Gonert, ejpi или Quicknote для файла с именем hildonize.py https://garage.maemo.org/plugins/ggit/browse.php/?p=gc-dialer.;a=blob;f=src/hildonize.py;

Еще один пример из GObject Utils от The One Ring (go_utils.py)

 def _old_timeout_add_seconds(timeout, callback):
         return gobject.timeout_add(timeout * 1000, callback)


 def _timeout_add_seconds(timeout, callback):
         return gobject.timeout_add_seconds(timeout, callback)


 try:
         gobject.timeout_add_seconds
         timeout_add_seconds = _timeout_add_seconds
 except AttributeError:
         timeout_add_seconds = _old_timeout_add_seconds
person Ed.    schedule 11.02.2010