7

我正在开发一个在 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 的问题,我只是想知道这是如何完成的。

4

3 回答 3

10

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

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

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

 spec = createSpec()

现在,在您有条件的其他任何地方,您只需调用必要的函数:

 spec.drawComboBox()

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

于 2010-01-07T18:09:02.717 回答
0

我制作了一个单独的模块来处理我在普通 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
于 2010-02-11T17:51:29.260 回答
0

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

于 2010-01-07T18:07:37.193 回答