Skip to content

Instantly share code, notes, and snippets.

@theodox
Last active December 24, 2018 08:14
Show Gist options
  • Save theodox/8a0e33065d25277bdff764ca7a7f2ccf to your computer and use it in GitHub Desktop.
Save theodox/8a0e33065d25277bdff764ca7a7f2ccf to your computer and use it in GitHub Desktop.
a mixin to use QT layouts as if they were context managers
def is_gui_item(obj):
return isinstance(obj, QWidget) or isinstance(obj, QLayout)
class LayoutCtxMixin(object):
PARENTED = set() # tracks all widgets that have already been added to avoid double counting
DEPTH = 0
def __enter__(self):
LayoutCtxMixin.DEPTH += 1
self.context = {id(self)}
try:
outer_f = inspect.currentframe().f_back
for v in outer_f.f_locals.values():
if is_gui_item(v):
self.context.add(id(v))
return self
finally:
del outer_f
def __exit__(self, *args):
try:
outer_f = inspect.currentframe().f_back
relevant_objects = (
(k, v) for k, v in outer_f.f_locals.items()
if is_gui_item(v) and
id(v) not in self.context and
id(v) not in self.PARENTED
)
for name, widget in relevant_objects:
if isinstance(widget, QLayout):
self.addLayout(widget)
else:
self.addWidget(widget)
if not name.startswith("_"):
widget.setObjectName(name)
self.PARENTED.add(id(widget))
self.layout()
LayoutCtxMixin.DEPTH -= 1
return False
finally:
del outer_f
if LayoutCtxMixin.DEPTH == 0:
self.PARENTED.clear()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment