i think there are some bugs in ui.SegmentedControl, which may have been part of the issue:
>>> import ui
>>> s=ui.SegmentedControl()
>>> s.subviews
Traceback (most recent call last):
File "<string>", line 1, in <module>
SystemError: /Users/ole/Development/xcode/Pythonista/python/Objects/tupleobject.c:54: bad argument to internal function
likewise, trying to add_subview to a segmentedcontrol causes pythonista to crash. ccc suggests avoiding except/pass pattern, which is good advice. in this case, the exception was caused by segmentedcontrol not having subviews, in which case using hasattr as a check is a more general way to avoid raising an exception in the first place.
as to your specific question, here are a few ways you can tackle the sort of tree traversal problem.
here is a method using yield to go depth first recursively... I think you originally wanted to do something like this.
# coding: utf-8
import ui
from collections import deque
def depthfirst(v):
'''recursivdly walk tree'''
if hasattr(v,'subviews'):
for sv in v.subviews:
yield sv
for n in depthfirst(sv):
yield n
here is another approach, which uses a custom iterator object, so can go depth first or breadth first, nonrecursively. to go depth first, you basically keep a stack (pushing subviews onto the stack). breadth first you use a fifo. the idea is to pop one view from the "todo queue", and add its sub views to the queue, and return the popped view. when there are no views left, edit (for iterations this means raising StopException)
class ViewWalker(object):
'''simple iterator for ui.View objects, capable of depth or breadth first traversal'''
def __init__(self,v,breadthfirst=False):
self._dq=deque([v])
self._bredth=breadthfirst
def __iter__(self):
'''required for iterator objects'''
return self
def next(self):
"""required for iterator objects. raise stopiteration once the queue is empty. """
if not self._dq:
raise StopIteration
#pop next view...
if self._breadth:
v=self._dq.popleft()# oldest entry (FIFO)
else:
v=self._dq.pop() # newest entry (stack)
#then push its subviews
if hasattr(v,'subviews'):
self._dq.extend(v.subviews)
return v
v=ui.load_view('test')
print 'depthfirst:', [s.name for s in ViewWalker(v)]
print 'breadthfirst:', [s.name for s in ViewWalker(v,True )]