-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RecycleView: Add behavior to set RV data using kv ids #6897
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks fine, though i think maybe it can be improved, see comment.
kivy/uix/recycleview/views.py
Outdated
sizing_attrs = RecycleDataAdapter._sizing_attrs | ||
for key, value in data.items(): | ||
if key not in sizing_attrs: | ||
name, *ids = key.split('.', maxsplit=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the star? the maxsplit makes it a 2-tuple, so we should be able to directly use the value without indexing on the next line.
Also, i think like ids
is not a great name here, as name
actually refer to a kv id, and ids
here would be a chain of one or more attributes.
And why the maxsplit actually? Do we really want to set an attribute with dots in it? wouldn't it be better to iterate on the names, getting the next value until the penultimate one and use setattr on this one?
wid, *attrs = key.split('.')
obj = self
for attr in attrs[:-1]:
obj = getattr(obj, attr)
setattr(obj, attrs[-1], value)
or would that cause issues i can't think of right now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the star? the maxsplit makes it a 2-tuple, so we should be able to directly use the value without indexing on the next line.
Because the maxsplit
is 1 we can have at most 2 items. But it could also be only 1. In the latter case, ids
will be empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, i think like ids is not a great name here, as name actually refer to a kv id, and ids here would be a chain of one or more attributes.
I feel like that's nitpicking because in the normal case it is the property name, except when it's interpreted as an id :) But also, I think you may have misunderstood what this is doing. Specifically, with the following KV examples:
MyRule:
street: ''
Label:
id: address
<RootRule@RecycleKVIDsDataViewBehavior>:
country: ''
Label:
id: phone
MyRule:
id: my_rule
Setting data
to [{'country': 'US', 'phone.text': '123456', 'my_rule.street': 'Home ave', 'my_rule.address.text': '555'}]
. Under the current code, my_rule
will have a attribute named address.text
created and set to 555
. That's because we don't recursively go through rules like your example code. We only allow accessing the ids
at the first level. Hence the only 1 split by period. Under your code, it would set the text
property of the address
widget to 555
.
The reason is that I don't think it would be common in kivy to set properties this way for sub rules and sub-sub rules etc. So I don't think we should complicate the API by adding this. Because once we add that it's hard to remove such functionality and I'd prefer to wait until this specifically is requested. And even then I think we can just add such recursive ids
access a doc recipe. For now, this API only allows setting the property of a widget named in the root rule of the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, i did think a recursive definition could be useful, but i agree it might be a strong commitment that we might not need to make.
Under the current code, my_rule will have a attribute named address.text created and set to 555
I think that's what i meant with "Do we really want to set an attribute with dots in it?", that seems like a weird requirement to me, and i think i'd rather produce an error, saying that recursive setting (what i would expect by putting dots in the key) is not supported, than create attributes with dots in them, that can only be accessed through getattr, and won't properly bind in kvlang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose we can raise an exception if there is more than one dot, in case users think that it does work recursively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I added that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i feel the exception message could be improved, i'm not sure i would immediately understand why it's a problem, but reading the doc of the class should help, and it's a cool feature.
Yeah, I agree the message can be improved. But I couldn't think of a way to state it without writing a essay so I figured explaining it in the docs will have to be sufficient :) |
Which kivy version will contain this change ? |
next RC or release of 2.0. |
Adds the
RecycleKVIDsDataViewBehavior
class. Fixes #6878.It's similar to the existing
RecycleDataViewBehavior
class, except that the data can signify properties of objects named with an id in KV. E.g. given a KV rule::Then setting the data list with
rv.data = [{'name.text': 'Kivy user', 'value.text': '12'}]
would automatically set the corresponding labels.