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

View File

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

View File

@ -54,7 +54,7 @@ class Cell(BoxLayout):
viewer = blocks.eval(viewer,l)
if isinstance(viewer,dict):
print('viewer = ', viewer)
w = blocks.widgetBuild(viewer,ancestor=self.row.part.datagrid)
w = blocks.widgetBuild(viewer)
self.add_widget(w)
return
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.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.widget_ids = {}
self.row_height = None
self.on_sizeTask = None
self.selected_rowid = None

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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