bugfix
This commit is contained in:
parent
d427730a06
commit
9cf729a676
@ -9,6 +9,7 @@ class BGColorBehavior(object):
|
||||
if color_level==-1:
|
||||
color_level = 0
|
||||
self.color_level = color_level
|
||||
self.bg_ready = False
|
||||
self.radius = radius
|
||||
self.bgcolor = []
|
||||
self.fgcolor = []
|
||||
@ -36,6 +37,7 @@ class BGColorBehavior(object):
|
||||
def on_bgcolor(self,o=None,v=None):
|
||||
if self.bgcolor == []:
|
||||
return
|
||||
|
||||
if self.canvas:
|
||||
with self.canvas.before:
|
||||
Color(*self.bgcolor)
|
||||
|
@ -4,6 +4,98 @@ from .threadcall import HttpClient
|
||||
from .utils import absurl
|
||||
from appPublic.registerfunction import RegisterFunction
|
||||
|
||||
class DataGraber(EventDispatcher):
|
||||
"""
|
||||
Graber format
|
||||
{
|
||||
"widgettype":"DataGraber",
|
||||
"options":{
|
||||
"dataurl":"first",
|
||||
"datarfname":"second",
|
||||
"target":"third",
|
||||
"params":
|
||||
"method":
|
||||
"pagging":"default false"
|
||||
}
|
||||
}
|
||||
if dataurl present, the DataGraber using this dataurl to get and
|
||||
return data
|
||||
else if datarfname present, it find a registered function named
|
||||
by 'datarfname' to return data
|
||||
else if datatarget present, it find the widget and uses target
|
||||
method(default is 'getValue') to return data
|
||||
else it return None
|
||||
"""
|
||||
def __init__(self, **kw):
|
||||
super().__init__()
|
||||
self.options = kw
|
||||
self.register_event_type('on_success')
|
||||
self.register_event_type('on_error')
|
||||
|
||||
def load(self, *args, **kw):
|
||||
dataurl = self.options.get('dataurl')
|
||||
if dataurl:
|
||||
return self.loadUrlData(*args, **kw)
|
||||
|
||||
rfname = self.options.get('datarfname')
|
||||
if rfname:
|
||||
return self.loadRFData(*args, **kw)
|
||||
|
||||
target = self.options.get('datatarget')
|
||||
if target:
|
||||
return self.loadTargetData(*args, **kw)
|
||||
return None
|
||||
|
||||
def loadUrlData(self, *args, **kw):
|
||||
dataurl = self.options.get('dataurl')
|
||||
hc = HttpClient()
|
||||
params = self.options.get('params',{}).copy()
|
||||
params.update(kw)
|
||||
method = self.options.get('method','GET')
|
||||
d = hc.get(dataurl, params=params,method=method)
|
||||
return d
|
||||
|
||||
def loadRFData(self, *args, **kw):
|
||||
rfname = self.options.get('datarfname')
|
||||
rf = RegisterFunction()
|
||||
f = rf.get(rfname)
|
||||
if not f:
|
||||
return None
|
||||
params = self.options.get('params',{}).copy()
|
||||
params.update(kw)
|
||||
try:
|
||||
d = f(**params)
|
||||
return d
|
||||
except Exception as e:
|
||||
Logger.info('blocks : Exception:%s',e)
|
||||
print_exc()
|
||||
return None
|
||||
|
||||
def loadTargetData(self, *args, **kw):
|
||||
target = self.options.get('datatarget')
|
||||
w = Factory.Blocks.getWidgetById(target)
|
||||
if not w:
|
||||
return None
|
||||
params = self.options.get('params',{}).copy()
|
||||
params.update(kw)
|
||||
method = params.get('method', 'getValue')
|
||||
if not has(w, method):
|
||||
return None
|
||||
try:
|
||||
f = getattr(w, method)
|
||||
d = f()
|
||||
return d
|
||||
except Exception as e:
|
||||
Logger.info('blocks : Exception %s', e)
|
||||
print_exc()
|
||||
return None
|
||||
|
||||
def on_success(self,d):
|
||||
pass
|
||||
|
||||
def on_error(self,e):
|
||||
pass
|
||||
|
||||
class DataLoader(EventDispatcher):
|
||||
def __init__(self,data_user):
|
||||
self.data_user = data_user
|
||||
@ -11,12 +103,6 @@ class DataLoader(EventDispatcher):
|
||||
self.register_event_type('on_success')
|
||||
self.register_event_type('on_error')
|
||||
|
||||
def success(self,o,d):
|
||||
self.dispatch('on_success',d)
|
||||
|
||||
def error(self,o,e):
|
||||
self.dispatch('on_error',e)
|
||||
|
||||
def on_success(self,d):
|
||||
pass
|
||||
|
||||
@ -27,7 +113,7 @@ class DataLoader(EventDispatcher):
|
||||
pass
|
||||
|
||||
class HttpDataLoader(DataLoader):
|
||||
def load(self):
|
||||
def load(self, *args, **kw):
|
||||
url = absurl(self.data_user.url,self.data_user.target.parenturl)
|
||||
method = self.data_user.method
|
||||
params = self.data_user.params.copy()
|
||||
@ -36,14 +122,16 @@ class HttpDataLoader(DataLoader):
|
||||
"rows":self.data_user.page_rows
|
||||
})
|
||||
hc = HttpClient()
|
||||
hc(url,
|
||||
method=method,
|
||||
params=params,
|
||||
callback=self.success,
|
||||
errback=self.error)
|
||||
try:
|
||||
r = hc(url, method=method, params=params)
|
||||
self.dispatch('on_success', r)
|
||||
return r
|
||||
except Exception as e:
|
||||
self.dispatch('on_error', e)
|
||||
|
||||
|
||||
class ListDataLoader(DataLoader):
|
||||
def load(self):
|
||||
def load(self, *args, **kw):
|
||||
p = self.data_user.curpage
|
||||
r = self.data_user.page_rows
|
||||
try:
|
||||
@ -52,12 +140,13 @@ class ListDataLoader(DataLoader):
|
||||
"total":len(self.data_user.data),
|
||||
"rows":s
|
||||
}
|
||||
self.success(self,d)
|
||||
self.dispatch('on_success', d)
|
||||
return d
|
||||
except Exception as e:
|
||||
self.error(self,e)
|
||||
self.dispatch('on_error', e)
|
||||
|
||||
class RegisterFunctionDataLoader(DataLoader):
|
||||
def load(self):
|
||||
def load(self, *args, **kw):
|
||||
rf = RegisterFunction()
|
||||
try:
|
||||
rfname = self.data_user.rfname
|
||||
@ -70,7 +159,9 @@ class RegisterFunctionDataLoader(DataLoader):
|
||||
"rows":self.data_user.page_rows
|
||||
})
|
||||
s = func(**params)
|
||||
self.success(self,s)
|
||||
self.dispatch('on_success', s)
|
||||
return s
|
||||
except Exception as e:
|
||||
self.error(self,e)
|
||||
self.dispatch('on_error', e)
|
||||
|
||||
|
||||
|
@ -14,6 +14,8 @@ from .i18n import I18n
|
||||
from .toolbar import Toolbar
|
||||
from .color_definitions import getColors
|
||||
from .bgcolorbehavior import BGColorBehavior
|
||||
from .dataloader import DataGraber
|
||||
from .ready import WidgetReady
|
||||
|
||||
"""
|
||||
form options
|
||||
@ -94,11 +96,11 @@ uitypes = {
|
||||
"wclass":SelectInput,
|
||||
},
|
||||
"text":{
|
||||
"orientation":"vertical",
|
||||
"orientation":"horizontal",
|
||||
"wclass":StrInput,
|
||||
"options":{
|
||||
"multiline":True,
|
||||
"height":9,
|
||||
"height":4,
|
||||
}
|
||||
},
|
||||
"teleno":{
|
||||
@ -114,11 +116,16 @@ class InputBox(BoxLayout):
|
||||
def __init__(self, form, **options):
|
||||
self.form = form
|
||||
self.options = options
|
||||
self.uitype = options.get('uitype','string')
|
||||
self.uitype = options.get('uitype',options.get('datatype','string'))
|
||||
self.uidef = uitypes[self.uitype]
|
||||
orientation = self.uidef['orientation']
|
||||
width = self.form.inputwidth
|
||||
height = self.form.inputheight
|
||||
if self.uitype == 'text':
|
||||
if not options.get('height'):
|
||||
self.options['height'] = 4
|
||||
height = self.options.get('height',4)
|
||||
|
||||
self.labelwidth = self.form.options['labelwidth']
|
||||
kwargs = {
|
||||
"orientation":orientation,
|
||||
@ -138,7 +145,6 @@ class InputBox(BoxLayout):
|
||||
self.bind(size=self.setSize,
|
||||
pos=self.setSize)
|
||||
self.register_event_type("on_datainput")
|
||||
self.register_event_type("on_ready")
|
||||
|
||||
def on_datainput(self,o,v=None):
|
||||
print('on_datainput fired ...',o,v)
|
||||
@ -150,7 +156,7 @@ class InputBox(BoxLayout):
|
||||
opts = {
|
||||
"orientation":"horizontal",
|
||||
"size_hint_y":None,
|
||||
"height":CSize(3)
|
||||
"height":CSize(2)
|
||||
}
|
||||
if self.labelwidth<=1:
|
||||
opts['size_hint_x'] = self.labelwidth
|
||||
@ -166,10 +172,6 @@ class InputBox(BoxLayout):
|
||||
"i18n":True,
|
||||
"text":label,
|
||||
"font_size":CSize(1),
|
||||
"size_hint_x":None,
|
||||
"width":CSize(len(label)),
|
||||
"size_hint_y":None,
|
||||
"height":CSize(3)
|
||||
}
|
||||
self.labeltext = Text(**kwargs)
|
||||
bl.add_widget(self.labeltext)
|
||||
@ -184,11 +186,12 @@ class InputBox(BoxLayout):
|
||||
options = self.uidef.get('options',{}).copy()
|
||||
options.update(self.options.get('uiparams',{}))
|
||||
options['allow_copy'] = True
|
||||
options['width'] = options.get('width',20)
|
||||
options['width'] = options.get('width',1)
|
||||
options['height'] = options.get('height',1)
|
||||
if self.options.get('tip'):
|
||||
options['hint_text'] = i18n(self.options.get('tip'))
|
||||
if self.options.get('hint_text'):
|
||||
options['hint_text'] = i18n(self.options.get('hint_text'))
|
||||
|
||||
Logger.info('Form: uitype=%s', self.uitype)
|
||||
self.input_widget = self.uidef['wclass'](**options)
|
||||
if self.options.get('readonly'):
|
||||
self.input_widget.disabled = True
|
||||
@ -201,7 +204,6 @@ class InputBox(BoxLayout):
|
||||
self.add_widget(self.input_widget)
|
||||
self.initflag = True
|
||||
self.input_widget.bind(on_focus=self.on_focus)
|
||||
self.dispatch('on_ready', self)
|
||||
|
||||
def check(self):
|
||||
d = self.getValue()
|
||||
@ -214,9 +216,6 @@ class InputBox(BoxLayout):
|
||||
|
||||
return True
|
||||
|
||||
def on_ready(self, obj):
|
||||
Logger.info('kivyblocks: Form input ready')
|
||||
|
||||
def clear(self):
|
||||
self.input_widget.setValue('')
|
||||
|
||||
@ -244,8 +243,8 @@ class InputBox(BoxLayout):
|
||||
|
||||
def defaultToolbar():
|
||||
return {
|
||||
"img_size":2,
|
||||
"text_size":1,
|
||||
"img_size":1.5,
|
||||
"text_size":0.7,
|
||||
"tools":[
|
||||
{
|
||||
"name":"__submit",
|
||||
@ -261,7 +260,7 @@ def defaultToolbar():
|
||||
|
||||
}
|
||||
|
||||
class Form(BGColorBehavior, BoxLayout):
|
||||
class Form(BGColorBehavior, WidgetReady, BoxLayout):
|
||||
def __init__(self, **options):
|
||||
self.options = options
|
||||
BoxLayout.__init__(self, orientation='vertical')
|
||||
@ -269,6 +268,7 @@ class Form(BGColorBehavior, BoxLayout):
|
||||
BGColorBehavior.__init__(self,
|
||||
color_level=self.options.get('color_level',-1),
|
||||
radius=self.options.get('radius',[]))
|
||||
WidgetReady.__init__(self)
|
||||
self.readiedInput = 0
|
||||
self.cols = self.options_cols = self.options.get('cols',1)
|
||||
if isHandHold() and Window.width < Window.height:
|
||||
@ -282,7 +282,28 @@ class Form(BGColorBehavior, BoxLayout):
|
||||
pass
|
||||
|
||||
def init(self):
|
||||
self.toolbar = Toolbar(**self.options.get('toolbar',defaultToolbar()))
|
||||
desc = defaultToolbar()
|
||||
desc1 = self.options.get('toolbar')
|
||||
if desc1:
|
||||
tools = desc['tools'] + desc1['tools']
|
||||
desc1['tools'] = tools
|
||||
desc = desc1
|
||||
if self.options.get('submit'):
|
||||
kw = self.options.get('submit').copy()
|
||||
if kw.get('name'):
|
||||
del kw['name']
|
||||
for t in desc['tools']:
|
||||
if t['name'] == '__submit':
|
||||
t.update(kw)
|
||||
if self.options.get('clear'):
|
||||
kw = self.options.get('clear').copy()
|
||||
if kw.get('name'):
|
||||
del kw['name']
|
||||
for t in desc['tools']:
|
||||
if t['name'] == '__clear':
|
||||
t.update(kw)
|
||||
|
||||
self.toolbar = Toolbar(**desc)
|
||||
self.fsc = VResponsiveLayout(
|
||||
self.inputwidth,
|
||||
self.cols
|
||||
@ -299,6 +320,11 @@ class Form(BGColorBehavior, BoxLayout):
|
||||
wid.bind(on_press=self.on_submit_button)
|
||||
wid = Factory.Blocks.getWidgetById('__clear',from_widget=self)
|
||||
wid.bind(on_press=self.on_clear_button)
|
||||
if self.options.get('dataloader'):
|
||||
self.dataloader = DataGraber(**self.options['dataloader'])
|
||||
d = self.dataloader.load()
|
||||
if d:
|
||||
self.setValue(d)
|
||||
|
||||
def makeInputLink(self,o,v=None):
|
||||
self.readiedInput += 1
|
||||
@ -309,6 +335,12 @@ class Form(BGColorBehavior, BoxLayout):
|
||||
w.input_widget.focus_previous = p.input_widget
|
||||
p = w
|
||||
|
||||
def setValue(self,d):
|
||||
for f in self.fieldWidgets:
|
||||
v = f.getValue()
|
||||
for k in v.keys():
|
||||
f.setValue({k:d[k]})
|
||||
|
||||
def getValue(self):
|
||||
d = {}
|
||||
for f in self.fieldWidgets:
|
||||
@ -367,6 +399,12 @@ class StrSearchForm(BoxLayout):
|
||||
}
|
||||
return d
|
||||
|
||||
def setValue(self, d):
|
||||
if isinstance(d,str):
|
||||
self.input_widget.text = d
|
||||
if isinstance(d,{}):
|
||||
self.input_widget.text = d.get(self.name,'')
|
||||
|
||||
def submit_input(self,o,v=None):
|
||||
text = self.input_widget.text
|
||||
if text != '':
|
||||
|
@ -15,7 +15,6 @@ from ..threadcall import HttpClient
|
||||
from ..utils import CSize
|
||||
|
||||
class BoolInput(Switch):
|
||||
change = BooleanProperty(False)
|
||||
def __init__(self,**kw):
|
||||
a = DictObject()
|
||||
if kw.get('defaultvalue',None) is None:
|
||||
@ -25,7 +24,7 @@ class BoolInput(Switch):
|
||||
if kw.get('value',None) is not None:
|
||||
a.active = kw.get('value')
|
||||
|
||||
super().__init__(**a)
|
||||
super().__init__(**a.to_dict())
|
||||
self.register_event_type('on_changed')
|
||||
self.bind(active=on_active)
|
||||
|
||||
@ -52,11 +51,9 @@ class StrInput(TextInput):
|
||||
"halign":"left",
|
||||
"hint_text":"",
|
||||
}
|
||||
if kv.get('tip'):
|
||||
a['hint_text'] = kv['tip']
|
||||
# a.update(kv)
|
||||
w = kv.get('width',20)
|
||||
h = kv.get('height',2.5)
|
||||
a.update(kv)
|
||||
w = kv.get('width',1)
|
||||
h = kv.get('height',1)
|
||||
if w <= 1:
|
||||
a['size_hint_x'] = w
|
||||
else:
|
||||
@ -67,9 +64,7 @@ class StrInput(TextInput):
|
||||
else:
|
||||
a['size_hint_y'] = None
|
||||
a['height'] = CSize(h)
|
||||
a['font_size'] = CSize(kv.get('font_size',1))
|
||||
a['password'] = kv.get('password',False)
|
||||
a['multiline'] = kv.get('multiline',False)
|
||||
a['font_size'] = CSize(kv.get('font_size',0.9))
|
||||
|
||||
Logger.info('TextInput:a=%s,kv=%s',a,kv)
|
||||
super(StrInput,self).__init__(**a)
|
||||
@ -107,6 +102,7 @@ class Password(StrInput):
|
||||
|
||||
class IntegerInput(StrInput):
|
||||
def __init__(self,**kw):
|
||||
print("IntegerInput(), __init__()....")
|
||||
a = {}
|
||||
a.update(kw)
|
||||
a['halign'] = 'right'
|
||||
@ -114,6 +110,7 @@ class IntegerInput(StrInput):
|
||||
|
||||
pat = re.compile('[^0-9]')
|
||||
def insert_text(self, substring, from_undo=False):
|
||||
print('TTTTTTTTTTTTTTTTTTTTTTttt')
|
||||
pat = self.pat
|
||||
s = re.sub(pat, '', substring)
|
||||
return StrInput.insert_text(self,s, from_undo=from_undo)
|
||||
@ -125,6 +122,7 @@ class IntegerInput(StrInput):
|
||||
class FloatInput(IntegerInput):
|
||||
pat = re.compile('[^0-9]')
|
||||
def filter(self,substring):
|
||||
print('FloatInput(), filter():..........')
|
||||
pat = self.pat
|
||||
if '.' in self.text:
|
||||
s = re.sub(pat, '', substring)
|
||||
@ -169,6 +167,7 @@ class MyDropDown(DropDown):
|
||||
self.setDataByUrl(self.url)
|
||||
else:
|
||||
self.si_data = self.options.get('data')
|
||||
if self.si_data:
|
||||
self.setData(self.si_data)
|
||||
self.bind(on_select=lambda instance, x: self.selectfunc(x))
|
||||
|
||||
@ -192,38 +191,29 @@ class MyDropDown(DropDown):
|
||||
def setData(self,data):
|
||||
self.si_data = data
|
||||
self.clear_widgets()
|
||||
w = self.options.get('width',10)
|
||||
h = self.options.get('height',2.5)
|
||||
a = {}
|
||||
if w <= 1:
|
||||
a['size_hint_x'] = w
|
||||
else:
|
||||
a['size_hint_x'] = None
|
||||
a['width'] = CSize(w)
|
||||
if h <= 1:
|
||||
a['size_hint_y'] = h
|
||||
else:
|
||||
a['size_hint_y'] = None
|
||||
a['height'] = CSize(h)
|
||||
a['font_size'] = CSize(self.options.get('font_size',1))
|
||||
print('data=',data)
|
||||
for d in data:
|
||||
dd = (d[self.valueField],d[self.textField])
|
||||
b = Button(text=d[self.textField],**a)
|
||||
setattr(b,'kw_data',dd)
|
||||
b.bind(on_release=lambda btn: self.select(btn.kw_data))
|
||||
self.add_widget(b)
|
||||
#print(dd)
|
||||
print('setData():',dd)
|
||||
|
||||
def setDataByUrl(self,url,params={}):
|
||||
def x(obj,d):
|
||||
def setDataByUrl(self,url,kw={}):
|
||||
hc = HttpClient()
|
||||
params = self.options.get('params', {}).copy()
|
||||
params.update(kw)
|
||||
d = hc.get(url,params=params)
|
||||
self.setData(d)
|
||||
|
||||
app = App.get_running_app()
|
||||
app.hc.get(url,params=params,callback=x)
|
||||
|
||||
|
||||
def showme(self,w):
|
||||
#print('show it ',w)
|
||||
print('show it ',w)
|
||||
self.target = w
|
||||
self.open(w)
|
||||
|
||||
@ -231,7 +221,7 @@ class SelectInput(BoxLayout):
|
||||
def __init__(self,**kw):
|
||||
a={}
|
||||
w = kw.get('width',10)
|
||||
h = kw.get('height',2.5)
|
||||
h = kw.get('height',1.5)
|
||||
if w <= 1:
|
||||
a['size_hint_x'] = w
|
||||
else:
|
||||
@ -245,11 +235,13 @@ class SelectInput(BoxLayout):
|
||||
|
||||
super(SelectInput,self).__init__(orientation='horizontal',\
|
||||
**a)
|
||||
self.tinp = StrInput(size_hint_y=None,height=kw.get('height',2.5))
|
||||
self.si_value = ''
|
||||
self.tinp = StrInput()
|
||||
self.tinp.readonly = True
|
||||
newkw = {}
|
||||
newkw.update(kw)
|
||||
newkw.update({'on_select':self.setData})
|
||||
print('selectinput:kw=', newkw)
|
||||
self.dropdown = MyDropDown(**newkw)
|
||||
if kw.get('value'):
|
||||
self.si_data = kw.get('value')
|
||||
@ -273,18 +265,18 @@ class SelectInput(BoxLayout):
|
||||
self.old_value = self.getValue()
|
||||
|
||||
def setData(self,d):
|
||||
self.tinp.si_data = d[0]
|
||||
self.si_value = d[0]
|
||||
self.tinp.text = d[1]
|
||||
v = self.getValue()
|
||||
if v != self.old_value:
|
||||
self.dispatch('on_changed',v)
|
||||
|
||||
def setValue(self,v):
|
||||
self.tinp.si_value = v
|
||||
self.si_value = v
|
||||
self.tinp.text = self.dropdown.getTextByValue(v)
|
||||
|
||||
def getValue(self):
|
||||
return self.tinp.si_value
|
||||
return self.si_value
|
||||
|
||||
if __name__ == '__main__':
|
||||
from kivy.app import App
|
||||
|
Loading…
Reference in New Issue
Block a user