Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Thinking out aloud, code gen for ui attr.
-
I mention in the comments of the code this is far from finished or polished. I am trying to get my head around a good uniform stradegy to implement some type of styles to any app I may write. I thought by writing this code, it will help me along the way. Just writes out a style class at the moment. Still thinking about the next steps. Will sleep on it.
''' this is sort of, just thinking out aloud code. i want a standard way to handle styles in all my projects. i was thinking to have a style class for each ui element. you create the class, assign your attributes then you pass it to some helper functions or methods in the class. this code, writes the classes to the console, which you could copy and paste into an empty script. its no were finished yet. no helper functions etc... also some logic problems in handling some of the attributes. i have fudged it were i needed to just to get the code working. fudged working code , better than no code. only sharing this now because someone may have valuable feedback. maybe the feedback is 'stop you idiot, is a waste of time, it has been done before, and a lot better than this!' regardless all feedback is good. i have not wasted my time though, even if the code is cluncky, i have learnt a lot by attempting it. ''' import ui import sys _INDENT_LEVEL_0 = ' ' * 0 _INDENT_LEVEL_1 =' ' * 2 _INDENT_LEVEL_2 = _INDENT_LEVEL_1 * 2 __NO_BASE = True ui_objects = [ui.View, ui.Button,ui.ButtonItem, ui.ImageView,ui.Label, ui.NavigationView, ui.ScrollView, ui.SegmentedControl, ui.Slider, ui.Switch, ui.TableView, ui.TableViewCell, ui.TextField, ui.TextView, ui.WebView, ui.DatePicker] _HEADER = ''' import datetime ''' def write_out(str): # i am writing to the console, can write to a file ect... print str def get_non_callable_attr_list(obj): ''' if this function performs correctly, a list of attributes for the given object will be returned in a list. i say if, meaning if i have stepped over the attributes that should not be returned correctly. ''' attr_list = [] attributes = dir(obj) for attr in attributes: if not callable(getattr(obj, attr)) and attr[:2] != '__' : attr_list.append(attr) return attr_list def write_cls_to_console(obj, base_attr): ''' this function does most the work. iterates over the already filtered attributes of an object, creates the object from the ui base object, then eval's' each attribute so we can write the default values to the class. had to fudge some values. more than i would have liked to. its ok, will go back and find a better stradegy to deal with the execptions. i say fudge, but i believe they are correct fudges. some attributes need special handling, i have just done a crappy linear job of handling them at the moment. there is awlays tomorrow. ''' attributes = get_non_callable_attr_list(obj) #this is a funny way to get the class name. it was the easiest i could come up with without adding more data. i tried a lot of different ways, i could not get it. however, i think there must be a better way... class_name = obj.__doc__.split(' ', 1)[0] write_out( _INDENT_LEVEL_0 + 'class ' + class_name + '_Style' + '(object):') write_out(_INDENT_LEVEL_1 + 'def __init__(self):') added_attr = 0 for attr in attributes: #if attr not in base_attr: # i was initally thinking to make a base class of attributes based on the attributes of ui.View and have each class inherit from the base class. i could see quickly this was not smart. i could have still done it with a call to the superclass to init the vars of the superclass, but in my mind self defeating. the commented if statement above would only write the attributes in each class whose attribte did not appear in ui.View if __NO_BASE: #create an actual instance of the object, so we can get the default attr settings using eval. new_obj = obj() # i know this try is bad. i am not sure why its failing at the moment... so we will move on. the first fail was on NavigationView, i am sure a few others fail also... try: x = eval('new_obj.' + attr) except : x = 'None' # another crappy check. if the eval equates to a memory object, we set to None if x: if 'object at' in str(x): x = None # yet another crappy check. see if len == 0 #flex and autoresizing come back as '' if type(x) == str: if not len(x) : x = "''" # last check.... i hope, will rethink these checks and redo the logic later if attr == 'text': x = "''" # and yet another execption...sh*t # only used for datepicker... if attr == 'date': x = 'datetime.datetime.today()' write_out(_INDENT_LEVEL_2 + 'self.' + attr + ' = ' + str(x)) added_attr += 1 if added_attr == 0: write_out(_INDENT_LEVEL_1 + 'pass') # this list not being used now. just creating a list of ui.View attributes. i was going to filter these attributes out if each class and inherit from a base class. does not make sense though. ui_View_attr = get_non_callable_attr_list(ui.View) # from here we just output the ui classes in the list ui_objects. i have used a function so the output can be easily be written to a file etc.. write_out(_HEADER) for obj in ui_objects: write_cls_to_console(obj, ui_View_attr) write_out('\n') # blank line please ;)
-
Not sure if this code useful to anyone. I got a bit closer to the ui elements and attributes by writing it. I am still a beginner, so if you are a beginner also, please be careful of my code. I have tried to be careful, but I only know what I know.
import ui import sys import console ''' UIClassAttrInfo this is a test class, collecting attribute information about ui elements. not meant for runtime, more a tool, not necessarily useful. ''' _nl = "\n" _sp = ' ' # list of the standard ui elements _ui_objects = [ui.View, ui.Button,ui.ButtonItem, ui.ImageView,ui.Label, ui.NavigationView, ui.ScrollView, ui.SegmentedControl, ui.Slider, ui.Switch, ui.TableView, ui.TableViewCell, ui.TextField, ui.TextView, ui.WebView, ui.DatePicker] # a list of attributes that can not filtered out automatically, but should not be exposed in this class. well, thats my opion, maybe wrong # if you dont ignore subviews, a error will occur # if you dont ignore, transform, content_view and text_label you will get an object reference in memory for the attr. seems like better to leave these out. # seems to be no references to autoresizing in the documentation. #i am guessing bg_color is in for backward compatibility. _attr_ignore = ['superview', 'subviews', 'transform','content_view', 'image_view', 'text_label','on_screen', 'autoresizing', 'bg_color' ] # a entry of attribute:value will replace the default attribute. _attr_override = {'font' : ('<system>', 18), 'tint_color' : "'white'", 'date':None, } class UIClassAttrInfo(object): def __init__(self, ui_element): if ui_element == ui.NavigationView: # this needs to be done for , # ui.NavigationView, otherwise,big fail self.obj = ui_element(ui.View()) else: self.obj = ui_element() obj = self.obj # mangle a class name from obj self.class_name = obj.__doc__.split(' ')[0] # get the settable attr names from ui.View self.uiView_attr = self.get_attr_names(ui.View()) # get the settable attr from the passed obj self.attr = self.get_attr_names(obj) #get the settable attr of obj that are not in ui.View self.u_attr = self.get_u_attr(self.uiView_attr,self.attr) self.attr_values = self.get_attr_values(obj, self.attr) def get_attr_names(self, obj): ''' get the settable attrs from the obj passed in. _attr_ignore, is looked up before adding the attr ''' attr_list=[] attributes = dir(obj) for attr in attributes: if attr in _attr_ignore: # _attr_ignore, a list of attrs to ignore pass else: try: if not callable(getattr(obj,attr)) and attr[:2] != '__' : attr_list.append(attr) except Exception as e: print '*' * 100 # make it obvious, Fail print 'we should not get here', 'get_attr_names', attr print e sys.exit(0) # do a hard exit! big fail return attr_list def get_u_attr( self, view_attr, obj_attr): # uses sets to get the attrs that are in the obj but not in the ui.View # could be useful return list(set.difference(set(obj_attr), set(view_attr))) def get_attr_values(self, obj, attrs): ''' make and return a dict of attr with the default values ''' lst = [] for attr in attrs: if attr in _attr_override: lst.append((attr, _attr_override[attr] )) else: try: x = eval('obj.' + attr) lst.append((attr, x)) except Exception as e: print '*' * 100 # make it obvious, Fail print 'we should not get here', 'make_attr_val', attr sys.exit(0) print e return lst def a_write_method(self): # an example of how this class could write out attribute classes. print 'class ' + self.class_name + 'AttrInfo(' + 'object' + '):' print _sp * 2 + 'def __init__(' + 'self ):' print _sp * 4 + 'self.attr_list =' + str(self.attr) print _nl print _sp * 4 + 'self.attr_list_u =' + str(self.u_attr) print _nl #write of the attr names with default values for t in self.attr_values: attr , val = t print _sp * 4 + 'self.' + attr + ' = ' + str( str(val) if len(str(val)) > 0 else "''") print _nl if __name__=='__main__': for obj in _ui_objects: # only collect the attribute cls_info = UIClassAttrInfo(obj) #write to the console cls_info.a_write_method() console.hud_alert('completed')