This commit is contained in:
yumoqing 2021-11-03 10:44:08 +08:00
parent aa94f34ea5
commit 2503a95fc4
2 changed files with 743 additions and 748 deletions

106
kivyblocks/blocks.py → kivyblocks/blocks.pyx Executable file → Normal file
View File

@ -1,7 +1,7 @@
import os
import sys
import codecs
import json
import ujson as json
from traceback import print_exc
import kivy
@ -38,9 +38,6 @@ from .orientationlayout import OrientationLayout
from .threadcall import HttpClient
from .register import *
def showError(e):
print('error',e)
class WidgetNotFoundById(Exception):
def __init__(self, id):
super().__init__()
@ -94,7 +91,7 @@ class ArgumentError(Exception):
class NotRegistedWidget(Exception):
def __init__(self,name):
def __init__(self, name:str):
super().__init__()
self.widget_name = name
@ -105,7 +102,7 @@ class NotRegistedWidget(Exception):
def __expr__(self):
return self.__str__()
def registerWidget(name,widget):
def registerWidget(name:str,widget):
globals()[name] = widget
@ -117,43 +114,22 @@ class Blocks(EventDispatcher):
self.register_event_type('on_failed')
self.env = GlobalEnv()
def set(self,k,v):
def set(self, k:str, v):
self.env[k] = v
def register_widget(self,name,widget):
def register_widget(self, name:str, widget:Widget):
globals()[name] = widget
def buildAction(self,widget,desc):
def buildAction(self, widget:Widget, desc):
conform_desc = desc.get('conform')
blocks = Blocks()
if not conform_desc:
return partial(blocks.uniaction, widget, desc)
l = {
}
body="""def action(widget, *args, **kw):
jsonstr='''%s'''
desc = json.loads(jsonstr)
conform_desc = desc.get('conform')
blocks = Blocks()
if not conform_desc:
blocks.uniaction(widget, desc,*args, **kw)
return
w = blocks.widgetBuild({
"widgettype":"Conform",
"options":conform_desc
})
w.bind(on_conform=partial(blocks.uniaction, widget, desc))
w.open()
print('Conform show.....')
""" % (json.dumps(desc))
exec(body,globals(),l)
f = l.get('action',None)
if f is None:
raise Exception('None Function')
func =partial(f,widget)
func =partial(blocks.conform_action,widget, desc)
return func
def eval(self,s,l):
def eval(self, s:str, l:dict):
g = {}
forbidens = [
"os",
@ -166,14 +142,17 @@ class Blocks(EventDispatcher):
if k not in forbidens:
g[k] = v
g['__builtins__'] = globals()['__builtins__'].copy()
"""
g['__builtins__'] = globals()['__builtins__']
g['__builtins__']['__import__'] = None
g['__builtins__']['__loader__'] = None
g['__builtins__']['open'] = None
"""
g.update(self.env)
return eval(s,g,l)
def getUrlData(self,url,method='GET',params={}, files={},
def getUrlData(self, url:str, method:str='GET',
params:dict={}, files:dict={},
callback=None,
errback=None,**kw):
@ -220,7 +199,7 @@ class Blocks(EventDispatcher):
print_exc()
return s
def arrayValueExpr(self,arr:list,localnamespace:dict={}):
def arrayValueExpr(self,arr:list,localnamespace:dict={}) -> list:
d = []
for v in arr:
if type(v) == type(''):
@ -238,7 +217,7 @@ class Blocks(EventDispatcher):
d.append(v)
return d
def dictValueExpr(self,dic:dict,localnamespace:dict={}):
def dictValueExpr(self,dic:dict,localnamespace:dict={}) -> dict:
d = {}
for k,v in dic.items():
if type(v) == type(''):
@ -255,7 +234,7 @@ class Blocks(EventDispatcher):
continue
d[k] = v
return d
def valueExpr(self,obj,localnamespace={}):
def valueExpr(self,obj,localnamespace:dict={}):
if type(obj) == type(''):
return self.strValueExpr(obj,localnamespace)
if type(obj) == type([]):
@ -266,7 +245,7 @@ class Blocks(EventDispatcher):
return self.dictValueExpr(obj,localnamespace)
return obj
def w_build(self,desc:dict):
def w_build(self,desc) -> Widget:
# print('w_build(),desc=',desc)
widgetClass = desc.get('widgettype',None)
if not widgetClass:
@ -305,7 +284,7 @@ class Blocks(EventDispatcher):
self.build_rest(widget,desc)
return widget
def build_attributes(self,widget,desc,t=None):
def build_attributes(self, widget:Widget,desc,t=None):
excludes = ['widgettype','options','subwidgets','binds']
for k,v in [(k,v) for k,v in desc.items() if k not in excludes]:
if isinstance(v,dict) and v.get('widgettype'):
@ -322,10 +301,10 @@ class Blocks(EventDispatcher):
setattr(widget,k,self.valueExpr(v,\
localnamespace={'self':widget}))
def build_rest(self, widget,desc,t=None):
def build_rest(self, widget:Widget,desc,t=None):
self.subwidget_total = len(desc.get('subwidgets',[]))
self.subwidgets = [ None for i in range(self.subwidget_total)]
pos = 0
cdef int pos = 0
for pos,sw in enumerate(desc.get('subwidgets',[])):
b = Blocks()
kw = self.valueExpr(sw.copy(),
@ -338,7 +317,7 @@ class Blocks(EventDispatcher):
localnamespace={'self':widget})
self.buildBind(widget,kw)
def buildBind(self,widget,desc):
def buildBind(self, widget:Widget, desc):
wid = desc.get('wid','self')
w = Blocks.getWidgetById(desc.get('wid','self'),from_widget=widget)
if not w:
@ -356,7 +335,7 @@ class Blocks(EventDispatcher):
w.bind(**{event:f})
# Logger.info('Block: %s bind built', str(desc))
def multipleAction(self, widget, desc, *args):
def multipleAction(self, widget:Widget, desc, *args):
desc1 = {k:v for k, v in desc.items() if k != 'actions'}
mydesc = desc1.copy()
for a in desc['actions']:
@ -364,7 +343,20 @@ class Blocks(EventDispatcher):
new_desc.update(a)
self.uniaction(widget,new_desc, *args)
def uniaction(self,widget,desc, *args):
def conform_action(self, widget:Widget, desc, *args):
conform_desc = desc.get('conform')
blocks = Blocks()
if not conform_desc:
blocks.uniaction(widget, desc,*args, **kw)
return
w = blocks.widgetBuild({
"widgettype":"Conform",
"options":conform_desc
})
w.bind(on_conform=partial(blocks.uniaction, widget, desc))
w.open()
def uniaction(self, widget:Widget, desc, *args):
Logger.info('Block: uniaction() called, desc=%s', str(desc))
acttype = desc.get('actiontype')
@ -385,7 +377,7 @@ class Blocks(EventDispatcher):
alert("actiontype(%s) invalid" % acttype,title='error')
def eventAction(self, widget, desc, *args):
def eventAction(self, widget:Widget, desc, *args):
target = self.get_target(widget, desc)
event = desc.get('dispatch_event')
if not event:
@ -403,12 +395,12 @@ class Blocks(EventDispatcher):
print_exc()
return
def get_target(self, widget, desc):
def get_target(self, widget:Widget, desc):
if not desc.get('target'):
return None
return Blocks.getWidgetById(desc.get('target'),from_widget=widget)
def blocksAction(self,widget,desc, *args):
def blocksAction(self, widget:Widget, desc, *args):
target = self.get_target(widget, desc)
add_mode = desc.get('mode','replace')
opts = desc.get('options').copy()
@ -417,7 +409,7 @@ class Blocks(EventDispatcher):
if d:
p.update(d)
opts['options'] = p
def doit(target,add_mode,o,w):
def doit(target:Widget, add_mode:str, o, w:Widget):
if target:
if add_mode == 'replace':
target.clear_widgets()
@ -433,7 +425,7 @@ class Blocks(EventDispatcher):
b.bind(on_failed=doerr)
b.widgetBuild(opts)
def urlwidgetAction(self,widget,desc, *args):
def urlwidgetAction(self, widget:Widget, desc, *args):
target = self.get_target(widget, desc)
add_mode = desc.get('mode','replace')
opts = desc.get('options').copy()
@ -464,7 +456,7 @@ class Blocks(EventDispatcher):
b.bind(on_failed=doerr)
b.widgetBuild(d)
def getActionData(self,widget,desc,*args):
def getActionData(self, widget:Widget, desc,*args):
data = {}
rtdesc = self.build_rtdesc(desc)
rt = self.get_rtdata(widget, rtdesc, *args)
@ -473,7 +465,7 @@ class Blocks(EventDispatcher):
data = keyMapping(data, desc.get('keymapping'))
return data
def registedfunctionAction(self, widget, desc, *args):
def registedfunctionAction(self, widget:Widget, desc, *args):
target = self.get_target(widget, desc)
rf = RegisterFunction()
name = desc.get('rfname')
@ -489,7 +481,7 @@ class Blocks(EventDispatcher):
params.update(d)
func(target, *args, **params)
def scriptAction(self, widget, desc, *args):
def scriptAction(self, widget:Widget, desc, *args):
script = desc.get('script')
if not script:
Logger.info('Block: scriptAction():desc(%s) target not found',
@ -524,7 +516,7 @@ class Blocks(EventDispatcher):
return {}
return rtdesc
def get_rtdata(self, widget, desc, *args):
def get_rtdata(self, widget:Widget, desc, *args):
"""
desc descript follow attributes
{
@ -577,7 +569,7 @@ class Blocks(EventDispatcher):
print_exc()
return {}
def methodAction(self, widget, desc, *args):
def methodAction(self, widget:Widget, desc, *args):
method = desc.get('method')
target = self.get_target(widget, desc)
if target is None:
@ -598,7 +590,7 @@ class Blocks(EventDispatcher):
else:
alert('%s method not found' % method)
def widgetBuild(self,desc):
def widgetBuild(self, desc):
"""
desc format:
{
@ -677,7 +669,7 @@ class Blocks(EventDispatcher):
return doit(desc)
@classmethod
def getWidgetById(self,id,from_widget=None):
def getWidgetById(self, id:str, from_widget:Widget=None) -> Widget:
def find_widget_by_id(id, from_widget):
if id=='self':
return from_widget

View File

@ -3,6 +3,7 @@
from distutils.core import setup
from setuptools import setup, find_packages
from Cython.Build import cythonize
from version import version
# usage:
@ -32,6 +33,8 @@ package_data = {
setup(
name="kivyblocks",
ext_modules=cythonize(
['kivyblocks/blocks.pyx']),
version=version,
# uncomment the following lines if you fill them out in release.py