This commit is contained in:
yumoqing 2020-11-19 12:22:16 +08:00
parent 619f6d4718
commit d489369e85
10 changed files with 76 additions and 96 deletions

View File

@ -189,18 +189,27 @@ class Blocks(EventDispatcher):
def getUrlData(self,url,method='GET',params={}, files={}, def getUrlData(self,url,method='GET',params={}, files={},
callback=None, callback=None,
errback=None,**kw): errback=None,**kw):
if url.startswith('file://'): if url.startswith('file://'):
filename = url[7:] filename = url[7:]
with codecs.open(filename,'r','utf-8') as f: with codecs.open(filename,'r','utf-8') as f:
b = f.read() b = f.read()
dic = json.loads(b) dic = json.loads(b)
callback(None,dic) callback(None,dic)
else: elif url.startswith('http://') or url.startswith('https://'):
h = HTTPDataHandler(url,method=method,params=params, h = HTTPDataHandler(url,method=method,params=params,
files=files) files=files)
h.bind(on_success=callback) h.bind(on_success=callback)
h.bind(on_error=errback) h.bind(on_error=errback)
h.handle() h.handle()
else:
config = getConfig()
url = config.uihome + url
return self.getUrlData(url,method=method,
params=params,
files=files,
callback=callback,
errback=errback, **kw)
def strValueExpr(self,s:str,localnamespace:dict={}): def strValueExpr(self,s:str,localnamespace:dict={}):
if not s.startswith('py::'): if not s.startswith('py::'):
@ -260,8 +269,8 @@ class Blocks(EventDispatcher):
return self.dictValueExpr(obj,localnamespace) return self.dictValueExpr(obj,localnamespace)
return obj return obj
def __build(self,desc:dict,ancestor=None): def __build(self,desc:dict):
print('__build(),desc=',desc) # print('__build(),desc=',desc)
widgetClass = desc.get('widgettype',None) widgetClass = desc.get('widgettype',None)
if not widgetClass: if not widgetClass:
print("__build(), desc invalid", desc) print("__build(), desc invalid", desc)
@ -275,34 +284,19 @@ class Blocks(EventDispatcher):
widget = klass(**opts) widget = klass(**opts)
if desc.get('parenturl'): if desc.get('parenturl'):
widget.parenturl = desc.get('parenturl') widget.parenturl = desc.get('parenturl')
ancestor = widget
except Exception as e: except Exception as e:
print('Error:',widgetClass,'not registered') print('Error:',widgetClass,'not registered')
print_exc() print_exc()
raise NotExistsObject(widgetClass) raise NotExistsObject(widgetClass)
if desc.get('id'): if desc.get('id'):
myid = desc.get('id') widget.widget_id = desc.get('id')
holder = ancestor
if myid[0] == '/':
myid = myid[1:]
app = App.get_running_app()
holder = app.root
if ancestor == widget:
app = App.get_running_app()
holder = app.root
if not hasattr(holder,'widget_ids'):
setattr(holder,'widget_ids',{})
holder.widget_ids[myid] = widget
widget.build_desc = desc widget.build_desc = desc
self.build_rest(widget,desc,ancestor) self.build_rest(widget,desc)
return widget return widget
def build_rest(self, widget,desc,ancestor,t=None): def build_rest(self, widget,desc,t=None):
bcnt = 0 bcnt = 0
btotal = len(desc.get('subwidgets',[])) btotal = len(desc.get('subwidgets',[]))
params={ params={
@ -322,10 +316,10 @@ class Blocks(EventDispatcher):
if hasattr(widget,'parenturl'): if hasattr(widget,'parenturl'):
w.parenturl = widget.parenturl w.parenturl = widget.parenturl
widget.add_widget(w) widget.add_widget(w)
print('bcnt=',bcnt,'btotal=',btotal,'desc=',desc) # print('bcnt=',bcnt,'btotal=',btotal,'desc=',desc)
if bcnt >= btotal: if bcnt >= btotal:
for b in desc.get('binds',[]): for b in desc.get('binds',[]):
print('buildBind() called',b) # print('buildBind() called',b)
blocks.buildBind(widget,b) blocks.buildBind(widget,b)
def doerr(o,e): def doerr(o,e):
@ -336,7 +330,7 @@ class Blocks(EventDispatcher):
b = Blocks() b = Blocks()
b.bind(on_built=f) b.bind(on_built=f)
b.bind(on_failed=doerr) b.bind(on_failed=doerr)
b.widgetBuild(sw, ancestor=ancestor) b.widgetBuild(sw)
if btotal == 0: if btotal == 0:
for b in desc.get('binds',[]): for b in desc.get('binds',[]):
@ -344,13 +338,13 @@ class Blocks(EventDispatcher):
def buildBind(self,widget,desc): def buildBind(self,widget,desc):
wid = desc.get('wid','self') wid = desc.get('wid','self')
w = self.getWidgetByIdPath(widget,wid) w = Blocks.getWidgetById(desc.get('wid','self'),from_widget=widget)
event = desc.get('event') event = desc.get('event')
if event is None: if event is None:
return return
f = self.buildAction(widget,desc) f = self.buildAction(widget,desc)
w.bind(**{event:f}) w.bind(**{event:f})
print('w=',w,event,desc) # print('w=',w,event,desc)
def uniaction(self,widget,desc, *args): def uniaction(self,widget,desc, *args):
acttype = desc.get('actiontype') acttype = desc.get('actiontype')
@ -367,7 +361,7 @@ class Blocks(EventDispatcher):
alert("actiontype(%s) invalid" % acttype,title='error') alert("actiontype(%s) invalid" % acttype,title='error')
def blocksAction(self,widget,desc, *args): def blocksAction(self,widget,desc, *args):
target = self.getWidgetByIdPath(widget, desc.get('target','self')) target = Blocks.getWidgetById(desc.get('target','self'),widget)
add_mode = desc.get('mode','replace') add_mode = desc.get('mode','replace')
opts = desc.get('options') opts = desc.get('options')
d = self.getActionData(widget,desc) d = self.getActionData(widget,desc)
@ -385,10 +379,10 @@ class Blocks(EventDispatcher):
b = Blocks() b = Blocks()
b.bind(on_built=partial(doit,target,add_mode)) b.bind(on_built=partial(doit,target,add_mode))
b.bind(on_failed=doerr) b.bind(on_failed=doerr)
b.widgetBuild(opts,ancestor=widget) b.widgetBuild(opts)
def urlwidgetAction(self,widget,desc, *args): def urlwidgetAction(self,widget,desc, *args):
target = self.getWidgetByIdPath(widget, desc.get('target','self')) target = Blocks.getWidgetById(desc.get('target','self'),widget)
add_mode = desc.get('mode','replace') add_mode = desc.get('mode','replace')
opts = desc.get('options') opts = desc.get('options')
d = self.getActionData(widget,desc) d = self.getActionData(widget,desc)
@ -411,20 +405,20 @@ class Blocks(EventDispatcher):
b = Blocks() b = Blocks()
b.bind(on_built=partial(doit,target,add_mode)) b.bind(on_built=partial(doit,target,add_mode))
b.bind(on_failed=doerr) b.bind(on_failed=doerr)
b.widgetBuild(d,ancestor=widget) b.widgetBuild(d)
def getActionData(self,widget,desc, *args): def getActionData(self,widget,desc,*args):
data = {} data = {}
if desc.get('datawidget',False): if desc.get('datawidget',False):
dwidget = self.getWidgetByIdPath(widget, dwidget = Blocks.getWidgetById(desc.get('datawidget','self'),widget)
desc.get('datawidget')) if dwidget and hasattr(dwidget,'getData'):
data = dwidget.getData() data = dwidget.getData()
if desc.get('keymapping'): if desc.get('keymapping'):
data = keyMapping(data, desc.get('keymapping')) data = keyMapping(data, desc.get('keymapping'))
return data return data
def registedfunctionAction(self, widget, desc, *args): def registedfunctionAction(self, widget, desc, *args):
target = self.getWidgetByIdPath(widget, desc.get('target','self')) target = Blocks.getWidgetById(desc.get('target','self'),widget)
rf = RegisterFunction() rf = RegisterFunction()
name = desc.get('rfname') name = desc.get('rfname')
func = rf.get(name) func = rf.get(name)
@ -435,14 +429,14 @@ class Blocks(EventDispatcher):
params = desc.get('params',{}) params = desc.get('params',{})
d = self.getActionData(widget,desc) d = self.getActionData(widget,desc)
params.update(d) params.update(d)
print('registedfunctionAction(),params=',params) # print('registedfunctionAction(),params=',params)
func(target, *args, **params) func(target, *args, **params)
def scriptAction(self, widget, desc, *args): def scriptAction(self, widget, desc, *args):
script = desc.get('script') script = desc.get('script')
if not script: if not script:
return return
target = self.getWidgetByIdPath(widget, desc.get('target','self')) target = Blocks.getWidgetById(desc.get('target','self'),widget)
d = self.getActionData(widget,desc) d = self.getActionData(widget,desc)
ns = { ns = {
"self":target, "self":target,
@ -453,7 +447,7 @@ class Blocks(EventDispatcher):
def methodAction(self, widget, desc, *args): def methodAction(self, widget, desc, *args):
method = desc.get('method') method = desc.get('method')
target = self.getWidgetByIdPath(widget, desc.get('target','self')) target = Blocks.getWidgetById(desc.get('target','self'),widget)
if hasattr(target,method): if hasattr(target,method):
f = getattr(target, method) f = getattr(target, method)
kwargs = desc.get('options',{}) kwargs = desc.get('options',{})
@ -463,7 +457,7 @@ class Blocks(EventDispatcher):
else: else:
alert('%s method not found' % method) alert('%s method not found' % method)
def widgetBuild(self,desc,ancestor=None): def widgetBuild(self,desc):
""" """
desc format: desc format:
{ {
@ -481,7 +475,7 @@ class Blocks(EventDispatcher):
desc = self.valueExpr(desc) desc = self.valueExpr(desc)
# Logger.info("blocks:%s",str(desc)) # Logger.info("blocks:%s",str(desc))
try: try:
widget = self.__build(desc,ancestor=ancestor) widget = self.__build(desc)
self.dispatch('on_built',widget) self.dispatch('on_built',widget)
if hasattr(widget,'ready'): if hasattr(widget,'ready'):
widget.ready() widget.ready()
@ -497,18 +491,12 @@ class Blocks(EventDispatcher):
name = desc['widgettype'] name = desc['widgettype']
if name == 'urlwidget': if name == 'urlwidget':
opts = desc.get('options') opts = desc.get('options')
parenturl = None url = opts.get('url')
url='' if url is None:
if ancestor: self.dispatch('on_failed',Exception('miss url'))
parenturl = ancestor.parenturl
try:
url = absurl(opts.get('url'),parenturl)
except Exception as e:
self.dispatch('on_failed',e)
def cb(o,d): def cb(o,d):
try: try:
d['parenturl'] = url
doit(d) doit(d)
except Exception as e: except Exception as e:
doerr(None,e) doerr(None,e)
@ -519,25 +507,26 @@ class Blocks(EventDispatcher):
return return
doit(desc) doit(desc)
def getWidgetByIdPath(self,widget,path): @classmethod
ids = path.split('/') def getWidgetById(self,id,from_widget=None):
if ids[0] == '': app = App.get_running_app()
app = App.get_running_app() if id in ['root','/self']:
widget = app.root return app.root
ids = ids[1:] if id=='self':
for id in ids: return from_widget
if id == 'self': if from_widget is None:
return widget from_widget = app.root
if not hasattr(widget, 'widget_ids'): if hasattr(from_widget,'widget_id'):
print('widget not found,path=',path,'id=',id,'ids=',ids) print('Blocks.getWidgetById():widget_id=',
raise WidgetNotFoundById(id) from_widget.widget_id,'id=',id)
if from_widget.widget_id == id:
widget = widget.widget_ids.get(id,None) return from_widget
if widget is None: for c in from_widget.children:
print('widget not found,path=',path,'id=',id,'ids=',ids) ret = Blocks.getWidgetById(id,from_widget=c)
raise WidgetNotFoundById(id) if ret:
return widget return ret
return None
def on_built(self,v=None): def on_built(self,v=None):
return return

View File

@ -133,14 +133,13 @@ class BoxViewer(WidgetReady, BoxLayout):
raise e raise e
options = self.options['viewer'].copy() options = self.options['viewer'].copy()
options['options']['record'] = rec options['options']['record'] = rec
options['options']['ancestor'] = self
options['options']['size_hint'] = None,None options['options']['size_hint'] = None,None
options['options']['width'] = self.box_width options['options']['width'] = self.box_width
options['options']['height'] = self.box_height options['options']['height'] = self.box_height
blocks = Factory.Blocks() blocks = Factory.Blocks()
blocks.bind(on_built=partial(doit,self,holders,index)) blocks.bind(on_built=partial(doit,self,holders,index))
blocks.bind(on_failed=doerr) blocks.bind(on_failed=doerr)
blocks.widgetBuild(options, ancestor=self) blocks.widgetBuild(options)
def on_scroll_stop(self,o,v=None): def on_scroll_stop(self,o,v=None):
if o.scroll_y <= 0.001: if o.scroll_y <= 0.001:

View File

@ -54,7 +54,7 @@ class Cell(BoxLayout):
viewer = blocks.eval(viewer,l) viewer = blocks.eval(viewer,l)
if isinstance(viewer,dict): if isinstance(viewer,dict):
print('viewer = ', viewer) print('viewer = ', viewer)
w = blocks.widgetBuild(viewer,ancestor=self.row.part.datagrid) w = blocks.widgetBuild(viewer)
self.add_widget(w) self.add_widget(w)
return return
if desc['header']: if desc['header']:
@ -234,7 +234,6 @@ class DataGrid(WidgetReady, BoxLayout):
self.header_bgcolor = options.get('header_bgcolor',[0.29,0.29,0.29,1]) self.header_bgcolor = options.get('header_bgcolor',[0.29,0.29,0.29,1])
self.body_bgcolor = options.get('body_bgcolor',[0.25,0.25,0.25,1]) self.body_bgcolor = options.get('body_bgcolor',[0.25,0.25,0.25,1])
self.color = options.get('color',[0.91,0.91,0.91,1]) self.color = options.get('color',[0.91,0.91,0.91,1])
self.widget_ids = {}
self.row_height = None self.row_height = None
self.on_sizeTask = None self.on_sizeTask = None
self.selected_rowid = None self.selected_rowid = None

View File

@ -15,10 +15,10 @@ class DoubleFace(WidgetReady, BoxLayout):
self.portrait_widget = None self.portrait_widget = None
blocks = Factory.Blocks() blocks = Factory.Blocks()
blocks.bind(on_built=self.landscape_build) blocks.bind(on_built=self.landscape_build)
blocks.widgetBuild(landscape,ancestor=self) blocks.widgetBuild(landscape)
blocks = Factory.Blocks() blocks = Factory.Blocks()
blocks.bind(on_built=self.portrait_build) blocks.bind(on_built=self.portrait_build)
blocks.widgetBuild(portrait,ancestor=self) blocks.widgetBuild(portrait)
self.on_size_task = None self.on_size_task = None
self.ready_task = None self.ready_task = None

View File

@ -188,7 +188,7 @@ class InputBox(BoxLayout):
self.input_widget = self.uidef['wclass'](**options) self.input_widget = self.uidef['wclass'](**options)
if self.options.get('readonly'): if self.options.get('readonly'):
self.input_widget.disabled = True self.input_widget.disabled = True
self.form.widget_ids[self.options['name']] = self.input_widget self.input_widget.widget_id = self.options['name']
self.add_widget(self.input_widget) self.add_widget(self.input_widget)
self.initflag = True self.initflag = True
self.input_widget.bind(on_focus=self.on_focus) self.input_widget.bind(on_focus=self.on_focus)
@ -259,7 +259,6 @@ class Form(BGColorBehavior, BoxLayout):
BoxLayout.__init__(self, orientation='vertical') BoxLayout.__init__(self, orientation='vertical')
self.color_level = self.options.get('color_level', 0) self.color_level = self.options.get('color_level', 0)
BGColorBehavior.__init__(self,color_level=self.color_level) BGColorBehavior.__init__(self,color_level=self.color_level)
self.widget_ids = {}
self.readiedInput = 0 self.readiedInput = 0
self.cols = self.options_cols = self.options.get('cols',1) self.cols = self.options_cols = self.options.get('cols',1)
if isHandHold() and Window.width < Window.height: if isHandHold() and Window.width < Window.height:
@ -284,12 +283,9 @@ class Form(BGColorBehavior, BoxLayout):
self.fsc.add_widget(w) self.fsc.add_widget(w)
self.fieldWidgets.append(w) self.fieldWidgets.append(w)
w.bind(on_ready=self.makeInputLink) w.bind(on_ready=self.makeInputLink)
blocks = App.get_running_app().blocks wid = Blocks.getWidgetById('__submit',from_widget=self)
# wid = self.widget_ids['__submit']
wid = blocks.getWidgetByIdPath(self,'__submit')
wid.bind(on_press=self.on_submit_button) wid.bind(on_press=self.on_submit_button)
wid = blocks.getWidgetByIdPath(self,'__clear') wid = Blocks.getWidgetById('__clear',from_widget=self)
# wid = self.widget_ids['__clear']
wid.bind(on_press=self.on_clear_button) wid.bind(on_press=self.on_clear_button)
def makeInputLink(self,o,v=None): def makeInputLink(self,o,v=None):

View File

@ -29,12 +29,12 @@ class OrientationLayout(WidgetReady, SwipeBehavior, FloatLayout):
blocks = Factory.Blocks() blocks = Factory.Blocks()
blocks.bind(on_built=self.main_widget_built) blocks.bind(on_built=self.main_widget_built)
blocks.bind(on_failed=self.widget_build_failed) blocks.bind(on_failed=self.widget_build_failed)
blocks.widgetBuild(self.main_widget, ancestor=self) blocks.widgetBuild(self.main_widget)
if isinstance(self.second_widget, dict): if isinstance(self.second_widget, dict):
blocks = Factory.Blocks() blocks = Factory.Blocks()
blocks.bind(on_built=self.second_widget_built) blocks.bind(on_built=self.second_widget_built)
blocks.bind(on_failed=self.widget_build_failed) blocks.bind(on_failed=self.widget_build_failed)
blocks.widgetBuild(self.second_widget, ancestor=self) blocks.widgetBuild(self.second_widget)
def isLandscape(self): def isLandscape(self):
return self.width > self.height return self.width > self.height
@ -47,7 +47,7 @@ class OrientationLayout(WidgetReady, SwipeBehavior, FloatLayout):
self.remove_widget(self.widget_second) self.remove_widget(self.widget_second)
self.second_flg = False self.second_flg = False
else: else:
print('add second widget ..') print('add second widget ..',self.widget_second)
self.add_widget(self.widget_second) self.add_widget(self.widget_second)
self.second_flg = True self.second_flg = True
self.on_size(self.size) self.on_size(self.size)

View File

@ -17,7 +17,7 @@ class ServerImageViewer(ObjectViewer):
"keep_ratio":True, "keep_ratio":True,
"source":url "source":url
}) })
w = blocks.widgetBuild(desc,ancestor=self) w = blocks.widgetBuild(desc)
if w is None: if w is None:
print('Error desc=',desc) print('Error desc=',desc)
return return

View File

@ -39,7 +39,7 @@ class TabsPanel(BGColorBehavior, TabbedPanel):
self.add_widget(TabbedPanelItem(text=text,content=w)) self.add_widget(TabbedPanelItem(text=text,content=w))
blocks = Factory.Blocks() blocks = Factory.Blocks()
blocks.bind(on_built=add) blocks.bind(on_built=add)
blocks.widgetBuild(desc,ancestor=self) blocks.widgetBuild(desc)
def add_tabs(self,*args): def add_tabs(self,*args):
for d in self.tabs_list: for d in self.tabs_list:

View File

@ -84,7 +84,7 @@ class ToggleItems(BGColorBehavior, BoxLayout):
print(desc,'error',e) print(desc,'error',e)
b.bind(on_built=partial(cb,c)) b.bind(on_built=partial(cb,c))
b.bind(on_failed=partial(eb,desc)) b.bind(on_failed=partial(eb,desc))
b.widgetBuild(desc,ancestor=self) b.widgetBuild(desc)
if len(self.item_widgets) > 0: if len(self.item_widgets) > 0:
self.item_widgets[0].selected() self.item_widgets[0].selected()

View File

@ -37,8 +37,7 @@ class Tool(ButtonBehavior, BGColorBehavior, BoxLayout):
def __init__(self,ancestor=None,**opts): def __init__(self,ancestor=None,**opts):
if ancestor is None: if ancestor is None:
ancestor = App.get_running_app().root ancestor = App.get_running_app().root
ancestor.widget_ids[opts['name']] = self self.widget_id = opts['name']
self.ancestor = ancestor
ButtonBehavior.__init__(self) ButtonBehavior.__init__(self)
BoxLayout.__init__(self, BoxLayout.__init__(self,
size_hint_y=None) size_hint_y=None)
@ -128,7 +127,6 @@ class Toolbar(BGColorBehavior, GridLayout):
h = ancestor h = ancestor
if not ancestor: if not ancestor:
h = App.get_runnung_app().root h = App.get_runnung_app().root
h.widget_ids['_home_'] = tool
self.tool_widgets[opt.name] = tool self.tool_widgets[opt.name] = tool
box = BoxLayout() box = BoxLayout()
box.add_widget(tool) box.add_widget(tool)
@ -171,7 +169,6 @@ class ToolPage(BGColorBehavior, BoxLayout):
def __init__(self,**opts): def __init__(self,**opts):
self.opts = DictObject(**opts) self.opts = DictObject(**opts)
self.parenturl = opts.get('parenturl',None) self.parenturl = opts.get('parenturl',None)
self.widget_ids = {}
if self.opts.tool_at in [ 'top','bottom']: if self.opts.tool_at in [ 'top','bottom']:
orient = 'vertical' orient = 'vertical'
else: else:
@ -196,14 +193,15 @@ class ToolPage(BGColorBehavior, BoxLayout):
self._show_page(obj.opts) self._show_page(obj.opts)
def show_firstpage(self,t=None): def show_firstpage(self,t=None):
d = self.widget_ids['_home_'] return
d = self.children[0]
d.dispatch('on_press') d.dispatch('on_press')
def init(self): def init(self):
self.initFlag = True self.initFlag = True
self.mywidgets = {} self.mywidgets = {}
self.content = BoxLayout() self.content = BoxLayout()
self.widget_ids['content'] = self.content self.content.widget_id = 'content'
for t in self.opts.tools: for t in self.opts.tools:
parenturl = None parenturl = None
if hasattr(self,'parenturl'): if hasattr(self,'parenturl'):
@ -218,7 +216,6 @@ class ToolPage(BGColorBehavior, BoxLayout):
else: else:
self.add_widget(self.content) self.add_widget(self.content)
self.add_widget(self.toolbar) self.add_widget(self.toolbar)
# Clock.schedule_once(self.show_firstpage,0.5)
if __name__ == '__main__': if __name__ == '__main__':
from blocksapp import BlocksApp from blocksapp import BlocksApp