What is a good way to express a hierarchical grouping of widgets in Python?

This is a Python style issue - my Python code works, I'm just looking for suggestions for a coding convention that will make the code easier to read / understand / debug.

In particular, I am working on a Python class that allows the caller to add widgets to the graphical user interface. To configure the GUI, the user must write a method that adds widgets (named or anonymous) to the widget area so that the widgets form a tree (as is usually the case in graphical interfaces).

So that the user can customize the widget tree without having to specify a name for each widget of the container (and then explicitly refer to this parent widget when adding a child widget), my API supports the concept of a โ€œparent widget stackโ€. When declaring a container widget, the user can specify to insert this widget on this stack, and then any additional widgets (which do not explicitly indicate the parent) will be added to the parent at the top of the stack by default. Here is a simple example of what I mean:

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 

This is convenient, but I find that when the hierarchy of the GUI becomes more complex, it becomes difficult to determine what challenge it is for itself. PopParentWidget () corresponds to the widget container. It's easy to insert too much or too little, and you end up with very funny, but unintended results in the GUI.

So my question is to get PopParentWidget () to accept the explicit name of the widgets (which I want to avoid because I don't want to specify each widget in the container), is there anything I can do to make pop pop Is the connection in the code more obvious to the eyes?

In C / C ++, I would do this with indentation, but with Python I am not allowed to do this. For example, I would like to be able to do this:

 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 

... but Python will raise an IndentationError if I am so creative.

+4
source share
1 answer

This situation, when you have a couple of opposing operations, calls the context manager . Instead of explicitly inserting and pulling container widgets onto / from the stack, you should wrap the children of the container in a with block. Based on the code given here, this can be implemented as something like

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

(Documentation for contextlib.contextmanager ).

Then your SetupGUI method will look like this:

 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') 

As you can see, the nesting is clear from the indentation, and there is no need to manually press and call.

+6
source

Source: https://habr.com/ru/post/1396760/


All Articles