Access a Subview Element (.pyui)
So, I’m trying to access a subview element located in a custom view made in a .pyui
I saw another post where they suggested to use...
a = sender.superview['view1']['subview']
And it worked, I used it for assigning an image to the imageview and changing the alpha of the whole custom view when a button is tapped:
def example(sender): def animation1(): #Here I “call” the subview element in the custom view d = sender.superview['view1']['image'] z = ui.Image.named('image01.PNG') d.image = z #Here I access only to the custom view view1 = sender.superview['view1'] view1.alpha = 1 ui.animate(animation1, duration=2)
Later in the same script I want to acces a Label and a button in another custom view and then change the Text and title when the button is tapped. I used the same structure of the first example but it still doesn’t work:
def example(sender): def animation1(): d = sender.superview['view2']['bFac'] d.title = 'Example Title' bla bla, more text ui.animate(animation1,duration=2)
When I run the program I get the error TypeError: 'NoneType' object is not subscriptable
I don’t know if I’m making understand my self Xd, I’m new in Pythonista, hopping someone can answer me.
I there! Actually, it is pretty simple. Just access the ‘text’ attribute of the ‘title’ element.
Same thing happened, It popped the NoneType error.
I may have answered a little fast. It seems like your label does not get initialized (since the NoneType)... I expect it is the bFac element that is not initialized but it could be that it just does not exist. Is the sender the button? If so, maybe the bFac object is not in the super view. Try printing the keys to the superview[‘view2’] to see if the bFac element is there.
@AlejandroDDD I think that sender.superview['view2'] does not exist and then is not subscriptable
@cvp your right, i was trying and it doesn’t call even the ‘view1’, but only happens now, I didn’t had that problem in the past function (the one of the example), so what am I doing wrong?
Thanks to both of you by the way.
As a way if debugging, print sender.superview.name to make sure you are in the view you think. Also
for v in sender.superview.subviews: print (v.name)
That list will be the names you can index using sender.superview[name]
You can repeat with the named view to see it's subviews' names.
I was thinking and maybe for getting out of the subview and running the other one, idk, but I thing the custom view with the subviews act like an independent ui.view()
Maybe use something like:
Am I right? (I tried it didn’t work)
Ok, let's start very basic.
Your views start at the root view -- the one you call present on -- and then are heirarchical going down . If you assign a name in the UI editor, you can refer to a subview by name, a but only from it's immediate superview.
Please do the following:. From your button action, call this method on sender.
def print_view(sender): root=sender while root.superview: root=root.superview print('root:', root.name, type(root)) def print_subviews(v, prefix): print(prefix, v.name, type(v)) for sv in v.subviews: print_subviews(v, prefix+'+') print_subviews(root,'')
That will print something like
Etc. Hopefully this helps explain your view heirarchy.
Note that often people create global variables, or attributes in the root view that point to deep subviews...
root=ui.load_view (....) root.input_box=root['view1']['textview1'] ....
Then you can simply refer to these in your callbacks functions without having to use superview/subview business in your callbacks. If your button takes action on a specific item, that ends up being cleaner. If instead you have 5 buttons using the same action, then you would use sender. Superview