【问题标题】:How do I deal with multiple common user interfaces?如何处理多个常见的用户界面?
【发布时间】:2011-01-02 14:34:53
【问题描述】:

我正在开发一个在 2 个不同平台上运行的 python 应用程序,即常规桌面 linux 和 Maemo 4。我们在这两个平台上都使用 PyGTK,但在 Maemo 上进行了一些小调整以使其看起来不错,这些已实现如下:

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

其中大约有 15 个 if 语句需要让 UI 在 Maemo 4 上看起来和运行良好。

这一直是非常易于管理的。问题是不久前发布了一个新版本的 Maemo(5,又名 fremantle),它与 Maemo 4 相比有一些很大的不同。我不想在整个 GUI 代码中添加一堆检查以让所有 3 个平台使用相同的代码库很好地工作,因为那样会变得混乱。我也不想为每个平台创建原始 GUI 代码的副本,而只是针对特定平台对其进行修改(我想尽可能多地重复使用代码)。

那么,对于基于相同核心 UI 代码的不同平台,略有不同的 UI 有哪些方法?我不认为这是一个特定于 python 或 Maemo 的问题,我只是想知道这是如何完成的。

【问题讨论】:

  • 平台之间有哪些不同的代码:回调、使用的小部件、小部件的排列方式(即在不同的容器或不同的顺序中),或者只是某些平台特定的属性小部件?
  • 对不起,我忘记了。以上就是全部了。在所有平台上,它的核心是 PyGTK,然后在 Maemo 4 上有一些 hildon 东西(Maemo 特定的小部件,它们有不同的名称/信号/等),然后在 Maemo 5 上有更多花哨的 hildon 东西和其他一些其他小部件,它们使应用程序更有用。此外,在 Maemo 5 版本中,我们希望支持旋转,这确实需要动态重新排列小部件。

标签: python user-interface pygtk code-reuse maemo


【解决方案1】:

您可以在工厂中完成大部分工作:

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

然后,在您的代码早期的某个地方,您只需调用该工厂:

 spec = createSpec()

现在,只要你有条件,你只要调用必要的函数:

 spec.drawComboBox()

只要drawComboBox(),处理特定于平台的任何事情,你应该状态良好。

【讨论】:

    【解决方案2】:

    您可以将需要执行的特定于平台的事情隔离到 platform 模块内的小一致命名函数中,使用您正在运行的平台创建正确的函数名称,然后 getattr 正确的名称并调用它. if/else 样板将会消失。

    【讨论】:

      【解决方案3】:

      我制作了一个单独的模块来处理我在普通 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;

      The One Ring 的 GObject Utils (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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多