This is possibly very stupid. It can be hard to know sometimes. The code below does not run as the pyui files are not included. It's more about the idea. I have added a pic to help explain, it's also pretty crappy 😱
Btw, I am going to stop using pyui to refer to a Pythonista designer file. Its listed as a UIFile, so I will call it that.
It's not that easy to explain, but I will try.
So, we can create a custom view class from a UIFile. nice. All the magic happens in ui.load_view plus the help of the pyui_bindings func from @JonB. This works extremely well now as @JonB perfected it to deal with custom attributes, globals etc....
So what if you want to make a new view that uses one or more of your coded classes that read from a UIFile. And the way you want to do it is in the new UIFile, you just want to a a custom view and set it to code object (hope that's clear). So in your new UIFile, you specify a root Custom View Class, which you provide the code for in your .py file. Then for your objects, you create a custom view in the designer, set its Custom Class View to your existing code object for that UIFile and they should magically appear.
As I said not easy to explain.
Well, if you have read this far, the kicker is I didn't resolve it 😂 I did a hack, inserted a constant (at least at the right place) not sure anything better can be done without @omz making some tweaks to ui.load_view.
Again, I am not sure this is important or not. I just have a feeling it could be. I am sure in some ways this is just easier by loading UIFiles into a view and then manipulating them. While, I am sure that's true, I think design wise reading/coercing a UIFile into a Custom class is so much better. Keeping in mind, I am still a self confessed newbie. My hope is that eventually, time permitting @omz will build this into ui anyway.
Anyway, below is some code and pic to show my meaning. I am showing the same view 4 times in the composition view, but the idea is that it could be any number of views made up of any number of different UIFiles.
import ui, editor
from random import choice
'''
Pythonista Forum - @Phuket2
'''
_themes = ['Dawn', 'Tomorrow', 'Solarized Light',
'Solarized Dark', 'Cool Glow', 'Gold', 'Tomorrow Night', 'Oceanic',
'Editorial']
def pyui_bindings(obj):
# JonB
def WrapInstance(obj):
class Wrapper(obj.__class__):
def __new__(cls):
return obj
return Wrapper
bindings = globals().copy()
bindings[obj.__class__.__name__]=WrapInstance(obj)
return bindings
class UIFileBase(ui.View):
def __init__(self, ui_file, *args, **kwargs):
ui.load_view(ui_file, pyui_bindings(self))
super().__init__(*args, **kwargs)
def add(self, p):
# do like this so we can add transformations here later
p.add_subview(self)
class Panel(UIFileBase):
def __init__(self, ui_file = None, *args, **kwargs):
# hmmm, when a pyui file references this class
# what comes first, the chicken or the egg?
if not ui_file:
ui_file = 'title_panel' # horrible, a constant here
super().__init__(ui_file, *args, **kwargs)
print('in Panel')
class Combo(UIFileBase):
# composite of other UIFiles
def __init__(self, ui_file=None, *args, **kwargs):
super().__init__(ui_file, *args, **kwargs)
class MyClass(ui.View):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if __name__ == '__main__':
_use_theme = True
w, h = 400, 400
f = (0, 0, w, h)
ui_file = 'title_panel'
style = 'sheet'
animated = False
mc = MyClass(ui_file, frame=f, bg_color='white')
if not _use_theme:
mc.name = 'No Theme'
mc.present(style = style, animated=animated)
else:
theme = choice(_themes)
mc.name = theme
editor.present_themed(mc, theme_name=theme, style=style, animated=animated)
'''
pf = ui.Rect(*mc.bounds.inset(20, 20))
pf.height = 150
v = Panel(ui_file, frame = pf )
v.add(mc)
'''
ui_file = 'comp'
pf = ui.Rect(*mc.bounds.inset(5, 5))
p = Combo(ui_file, frame = pf)
p.add(mc)
