Skip to content

Instantly share code, notes, and snippets.

@gottadiveintopython
Last active July 29, 2019 00:44
Show Gist options
  • Save gottadiveintopython/3fc3a140aa3b0c3212ed93202f6eae59 to your computer and use it in GitHub Desktop.
Save gottadiveintopython/3fc3a140aa3b0c3212ed93202f6eae59 to your computer and use it in GitHub Desktop.
listing the children that will be added by Builder
__all__ = ('get_tree_from_widget', 'get_tree_from_root_rule', 'get_tree_from_cls', )
from kivy.lang import Parser, Builder, BuilderBase
from kivy.factory import Factory
def _get_children(rule):
return [{crule.name: _get_children(crule)} for crule in rule.children]
def get_tree_from_widget(widget):
return [
{crule.name: _get_children(crule)}
for rule in Builder.match(widget)
for crule in rule.children
]
def _match2(widget_cls):
'''same as BuilderBase.match() except it takes widget-class'''
cache = BuilderBase._match_cache
k = (widget_cls, tuple())
if k in cache:
return cache[k]
rules = []
for selector, rule in Builder.rules:
if selector.match(widget):
if rule.avoid_previous_rules:
del rules[:]
rules.append(rule)
cache[k] = rules
return rules
def get_tree_from_cls(widget_cls):
return [
{crule.name: _get_children(crule)}
for rule in _match2(widget_cls)
for crule in rule.children
]
def get_tree_from_root_rule(kvcode):
root_rule = Parser(content=kvcode).root
if not root_rule:
raise ValueError('There is no root rule.')
return [
*get_tree_from_cls(Factory.get(root_rule.name)),
_get_children(root_rule)
]
def _test():
import textwrap
import json
def print_widget_tree(widget_tree):
print(json.dumps(widget_tree, indent=2))
class MyWidget(Factory.BoxLayout):
def apply_class_lang_rules(self, *args, **kwargs):
# This is the only place that `get_tree_from_widget()` can be used.
print_widget_tree(get_tree_from_widget(self))
return super().apply_class_lang_rules(*args, **kwargs)
KV_CODE = textwrap.dedent('''
<MyWidget>:
Label:
text: '1st'
Label:
text: '2nd'
<MyWidget>:
BoxLayout:
Label:
text: '3rd'
''')
Builder.load_string(KV_CODE)
print('test get_tree_from_widget()')
MyWidget()
print('\n-----------------------')
print('test get_tree_from_cls()')
print_widget_tree(get_tree_from_cls(MyWidget))
print('\n-----------------------')
print('test get_tree_from_root_rule()')
print_widget_tree(get_tree_from_root_rule(textwrap.dedent('''
MyWidget:
Button:
''')))
if __name__ == "__main__":
_test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment