在Python中表达小部件的分层分组有什么好方法?

这是一个Python风格的问题 – 我的Python代码有效,我只是在寻找一种编码约定的建议,这将使代码更容易阅读/理解/调试.

具体来说,我正在开发一个Python类,它允许调用者将小部件添加到自定义GUI.为了设置GUI,用户将编写一个方法,将小部件(命名或匿名)添加到小部件区域,以便小部件形成树(在GUI中很常见).

为了允许用户设置窗口小部件树而不必为每个容器窗口小部件命名(然后在每次添加子窗口小部件时显式引用该父窗口小部件),我的API支持“父窗口小部件”的概念堆”.在声明容器窗口小部件时,用户可以指定将该窗口小部件推送到此堆栈,然后默认情况下,任何其他窗口小部件(未明确指定父窗口)将添加到堆栈顶部的父窗口.这是我的意思的一个简单例子:

def SetupGUI(self):
   self.AddWidget(name="root", type="container", push=True)

   self.AddWidget(type="container", push=True)
   for i in range(0,8):
      self.AddWidget(name="button%i"%i, type="button")
   self.PopParentWidget()  # pop the buttons-container off the parents-stack

   self.AddWidget(type="container", push=True)
   for i in range(0,8):
      self.AddWidget(name="slider%i"%i, type="slider")
   self.PopParentWidget()  # pop the sliders-container off the parents-stack

   self.PopParentWidget()  # pop the container "root" off the parents-stack

这很方便,但我发现当GUI层次结构变得更复杂时,开始变得难以分辨哪个对self.PopParentWidget()的调用对应于哪个容器小部件.很容易放入太多,或者太少,并最终在GUI中产生非常有趣但无意的结果.

所以我的问题是,没有强迫PopParentWidget()采用一个显式的小部件名称(我想避免,因为我不想命名每个容器小部件),有什么我可以做的推动/代码中的pop配对对眼睛更明显?

在C/C++中,我会使用缩进来做,但使用Python我不允许这样做.例如,我希望能够做到这一点:

def SetupGUI(self):
   self.AddWidget(name="root", type="container", push=True)
      self.AddWidget(type="container", push=True)
         for i in range(0,8):
            self.AddWidget(name="button%i"%i, type="button")
         self.PopParentWidget()  # pop the buttons-container off the parents-stack
      self.AddWidget(type="container", push=True)
         for i in range(0,8):
            self.AddWidget(name="slider%i"%i, type="slider")
         self.PopParentWidget()  # pop the sliders-container off the parents-stack
      self.PopParentWidget()  # pop the container "root" off the parents-stack

…但是如果我有这样的创意,Python会抛出IndentationError.

解决方法:

这种情况 – 你有一对相反的操作 – 调用a context manager.而不是显式地将容器小部件推入堆栈或从堆栈弹出容器小部件,而是将容器的子容器包装在一个with块中.基于您在此处显示的代码,可以将其实现为类似

@contextlib.contextmanager
def container(self, name=None):
    self.AddWidget(name=name, type='container', push=True)
    yield
    self.PopParentWidget()

(contextlib.contextmanager的文件).

然后,您的SetupGUI方法变为:

def SetupGUI(self):
    with self.container(name='root'):
        with self.container():
            for i in range(0,8):
                self.AddWidget(name='button%i' % i, type='button')
        with self.container():
            for i in range(0,8):
                self.AddWidget(name='slider%i' % i, type='slider')

正如您所看到的,嵌套从缩进中清晰可见,并且无需手动推送和弹出.

上一篇:将样式应用于Android ListView


下一篇:在Android中覆盖EditText的样式