Last active
July 29, 2019 00:44
-
-
Save gottadiveintopython/3fc3a140aa3b0c3212ed93202f6eae59 to your computer and use it in GitHub Desktop.
listing the children that will be added by Builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__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