This commit is contained in:
yumoqing 2021-02-26 15:50:20 +08:00
parent c42b0f4c9e
commit e47adf5c9a
9 changed files with 188 additions and 65 deletions

View File

@ -425,9 +425,10 @@ class Blocks(EventDispatcher):
if d: if d:
params.update(d) params.update(d)
try: try:
target.dispatch(event, **params) target.dispatch(event, params)
except Exception as e: except Exception as e:
Logger.info(f'Block: eventAction():dispatch {event} error') Logger.info(f'Block: eventAction():dispatch {event} error')
print_exc()
return return
def blocksAction(self,widget,desc, *args): def blocksAction(self,widget,desc, *args):

View File

@ -96,7 +96,7 @@ class BlocksApp(App):
x = blocks.widgetBuild(config.root) x = blocks.widgetBuild(config.root)
if x is None: if x is None:
alert('buildError,Exit', title='Error') alert('buildError,Exit', title='Error')
self.on_close() return Label(text='error')
return x return x
def get_user_data_path(self): def get_user_data_path(self):

View File

@ -110,6 +110,12 @@ class BoxViewer(WidgetReady, BoxLayout):
x = self.dataloader.getLocater() x = self.dataloader.getLocater()
self.locater(x) self.locater(x)
def loadData(self, **kw):
self.params = kw
self.deleteAllWidgets(None)
self.dataloader.loadPage(1)
self.initflag = True
def deleteWidgets(self,o,data): def deleteWidgets(self,o,data):
for w in data: for w in data:
self.viewContainer.remove_widget(w) self.viewContainer.remove_widget(w)

View File

@ -33,18 +33,29 @@ class DataGraber(EventDispatcher):
self.register_event_type('on_error') self.register_event_type('on_error')
def load(self, *args, **kw): def load(self, *args, **kw):
ret = None
while True:
try:
dataurl = self.options.get('dataurl') dataurl = self.options.get('dataurl')
if dataurl: if dataurl:
return self.loadUrlData(*args, **kw) ret = self.loadUrlData(*args, **kw)
break
rfname = self.options.get('datarfname') rfname = self.options.get('datarfname')
if rfname: if rfname:
return self.loadRFData(*args, **kw) ret = self.loadRFData(*args, **kw)
break
target = self.options.get('datatarget') target = self.options.get('datatarget')
if target: ret = self.loadTargetData(*args, **kw)
return self.loadTargetData(*args, **kw) break
return None except Exception as e:
self.dispatch('on_error', e)
return
if ret:
self.dispatch('on_success',ret)
else:
e = Exception('Not method to do load')
self.dispatch('on_error', e)
def loadUrlData(self, *args, **kw): def loadUrlData(self, *args, **kw):
dataurl = self.options.get('dataurl') dataurl = self.options.get('dataurl')
@ -52,7 +63,7 @@ class DataGraber(EventDispatcher):
params = self.options.get('params',{}).copy() params = self.options.get('params',{}).copy()
params.update(kw) params.update(kw)
method = self.options.get('method','GET') method = self.options.get('method','GET')
d = hc.get(dataurl, params=params,method=method) d = hc(dataurl, params=params,method=method)
return d return d
def loadRFData(self, *args, **kw): def loadRFData(self, *args, **kw):

View File

@ -164,6 +164,8 @@ class Header(WidgetReady, BGColorBehavior, ScrollWidget):
BGColorBehavior.__init__(self,color_level=color_level) BGColorBehavior.__init__(self,color_level=color_level)
self.init(1) self.init(1)
self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop) self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop)
if self.part.freeze_flag:
self.bar_width = 0
def init(self,t): def init(self,t):
rd = [ f.copy() for f in self.part.rowdesc ] rd = [ f.copy() for f in self.part.rowdesc ]
@ -180,6 +182,8 @@ class Body(ScrollWidget):
ScrollWidget.__init__(self,**kw) ScrollWidget.__init__(self,**kw)
self.idRow = {} self.idRow = {}
self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop) self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop)
if self.part.freeze_flag:
self.bar_width = 0
def addRow(self,id, data,index=0): def addRow(self,id, data,index=0):
rd = [ f.copy() for f in self.part.rowdesc ] rd = [ f.copy() for f in self.part.rowdesc ]

View File

@ -126,7 +126,7 @@ class InputBox(BoxLayout):
self.options['height'] = 4 self.options['height'] = 4
height = self.options.get('height',4) height = self.options.get('height',4)
self.labelwidth = self.form.options['labelwidth'] self.labelwidth = self.form.labelwidth
kwargs = { kwargs = {
"orientation":orientation, "orientation":orientation,
} }
@ -261,74 +261,146 @@ def defaultToolbar():
} }
class Form(BGColorBehavior, WidgetReady, BoxLayout): class Form(BGColorBehavior, WidgetReady, BoxLayout):
def __init__(self, **options): def __init__(self,
self.options = options color_level=1,
BoxLayout.__init__(self, orientation='vertical') radius=[],
self.color_level = self.options.get('color_level', 0) cols=2,
BGColorBehavior.__init__(self, inputwidth=0,
color_level=self.options.get('color_level',-1), inputheight=3,
radius=self.options.get('radius',[])) labelwidth=0.3,
WidgetReady.__init__(self) notoolbar=False,
toolbar_at='top', #'top', 'bottom', 'left', 'right'
dataloader={},
fields=[],
submit={},
clear={},
toolbar={},
**options):
self.inputwidth = 1
self.inputheight = inputheight
self.labelwidth= labelwidth
self.fields = fields
self.notoolbar = notoolbar
self.submit = submit
self.clear = clear
self.toolbar = toolbar
self.toolbar_at=toolbar_at
self.dataloader = dataloader
self.readiedInput = 0 self.readiedInput = 0
self.cols = self.options_cols = self.options.get('cols',1) if self.toolbar_at in ['top','bottom']:
options['orientation'] = 'vertical'
else:
options['orientation'] = 'horizontal'
BoxLayout.__init__(self, **options)
self.color_level = color_level
BGColorBehavior.__init__(self,
color_level=color_level,
radius=radius)
WidgetReady.__init__(self)
self.cols = self.options_cols = cols
if isHandHold() and Window.width < Window.height: if isHandHold() and Window.width < Window.height:
self.cols = 1 self.cols = 1
self.inputwidth = Window.width / self.cols self.options = options
self.inputheight = self.options.get('inputheight',3)
self.init() self.init()
self.register_event_type('on_submit') self.register_event_type('on_submit')
def on_size(self, *args): def on_size(self, *args):
pass if not hasattr(self,'fsc'):
return
if not self.notoolbar:
if self.toolbar_at in ['top', 'bottom']:
self.fsc.height = self.height - self.toolbar.height
else:
self.fsc.width = self.width - self.toolbar.width
else:
if self.toolbar_at in ['top', 'bottom']:
self.fsc.height = self.height
else:
self.fsc.width = self.width
self.fsc.org_box_width = self.width / self.options_cols
if self.notoolbar:
return
if self.toolbar_at in [ 'top', 'bottom' ]:
Logger.info('Form: height:tb:%d,ti:%d,fsc:%d, fm:%d',
self.toolbar.height,
self.toolbar.toggle_items.height,
self.fsc.height, self.height
)
else:
Logger.info('Form: width:tb:%d,ti:%d,fsc:%d, fm:%d',
self.toolbar.width,
self.toolbar.toggle_items.width,
self.fsc.width, self.width
)
def init(self): def init(self):
if not self.notoolbar:
desc = defaultToolbar() desc = defaultToolbar()
desc1 = self.options.get('toolbar') desc1 = self.toolbar
if desc1: if desc1:
tools = desc['tools'] + desc1['tools'] tools = desc['tools'] + desc1['tools']
desc1['tools'] = tools desc1['tools'] = tools
desc = desc1 desc = desc1
if self.options.get('submit'): if self.submit:
kw = self.options.get('submit').copy() kw = self.submit.copy()
if kw.get('name'): if kw.get('name'):
del kw['name'] del kw['name']
for t in desc['tools']: for t in desc['tools']:
if t['name'] == '__submit': if t['name'] == '__submit':
t.update(kw) t.update(kw)
if self.options.get('clear'): if self.clear:
kw = self.options.get('clear').copy() kw = self.clear.copy()
if kw.get('name'): if kw.get('name'):
del kw['name'] del kw['name']
for t in desc['tools']: for t in desc['tools']:
if t['name'] == '__clear': if t['name'] == '__clear':
t.update(kw) t.update(kw)
if self.toolbar_at in ['top', 'bottom']:
desc['orientation'] = 'horizontal'
desc['size_hint_y'] = None
desc['height'] = CSize(desc['img_size'] + desc['text_size'])
else:
desc['orientation'] = 'vertical'
desc['size_hint_x'] = None
desc['width'] = CSize(desc['img_size'] + desc['text_size'])
self.toolbar = Toolbar(**desc) self.toolbar = Toolbar(**desc)
self.fsc = VResponsiveLayout( self.fsc = VResponsiveLayout(
self.inputwidth, self.inputwidth,
self.cols self.cols,
size_hint=(1,1)
) )
if self.toolbar_at in ['top', 'left'] and not self.notoolbar:
self.add_widget(self.toolbar) self.add_widget(self.toolbar)
self.add_widget(self.fsc) self.add_widget(self.fsc)
if self.toolbar_at in ['bottom', 'right'] and not self.notoolbar:
self.add_widget(self.toolbar)
self.fieldWidgets=[] self.fieldWidgets=[]
for f in self.options['fields']: for f in self.fields:
w = InputBox(self, **f) w = InputBox(self, **f)
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)
wid = Factory.Blocks.getWidgetById('__submit',from_widget=self) wid = Factory.Blocks.getWidgetById('__submit',from_widget=self)
if wid:
wid.bind(on_press=self.on_submit_button) wid.bind(on_press=self.on_submit_button)
wid = Factory.Blocks.getWidgetById('__clear',from_widget=self) wid = Factory.Blocks.getWidgetById('__clear',from_widget=self)
if wid:
wid.bind(on_press=self.on_clear_button) wid.bind(on_press=self.on_clear_button)
if self.options.get('dataloader'): if self.dataloader:
self.dataloader = DataGraber(**self.options['dataloader']) self.loader = DataGraber(**self.dataloader)
d = self.dataloader.load() d = self.loader.load()
if d: if d:
self.setValue(d) self.setValue(d)
self.on_size()
def makeInputLink(self,o,v=None): def makeInputLink(self,o,v=None):
self.readiedInput += 1 self.readiedInput += 1
if self.readiedInput >= len(self.options['fields']): if self.readiedInput >= len(self.fields):
p = self.fieldWidgets[0] p = self.fieldWidgets[0]
for w in self.fieldWidgets[1:]: for w in self.fieldWidgets[1:]:
p.input_widget.focus_next = w.input_widget p.input_widget.focus_next = w.input_widget

View File

@ -23,20 +23,37 @@ class NewVideo(BGColorBehavior, Video):
Window.allow_screensaver = False Window.allow_screensaver = False
set_log_callback(self.ffplayerLog) set_log_callback(self.ffplayerLog)
self.register_event_type('on_open_failed') self.register_event_type('on_open_failed')
self.register_event_type('on_load_success')
self.bind(source=self.record_start_time)
self.load_status = None
def on_load_success(self, *args):
pass
def record_start_time(self, *args):
self.start_time = time.time()
self.load_status = 'start'
def on_open_failed(self, source, x=None): def on_open_failed(self, source, x=None):
print('source=',source, 'open failed') Logger.error(f'NewVideo: source={self.source} open failed')
self.load_status = 'failed'
def ffplayerLog(self, msg, level): def ffplayerLog(self, msg, level):
"""
if 'Connection to tcp' in msg and 'failed' in msg: if 'Connection to tcp' in msg and 'failed' in msg:
self.dispatch('on_open_failed', self.source) self.dispatch('on_open_failed', self.source)
if 'Invalid data found when processing input' in msg: if 'Invalid data found when processing input' in msg:
self.dispatch('on_open_failed', self.source) self.dispatch('on_open_failed', self.source)
if 'End of file' in msg: if 'End of file' in msg:
self.dispatch('on_open_failed', self.source) self.dispatch('on_open_failed', self.source)
if 'I/O error' in msg:
self.dispatch('on_open_failed', self.source)
if 'Server returned 404 Not Found' in msg: if 'Server returned 404 Not Found' in msg:
self.dispatch('on_open_failed', self.source) self.dispatch('on_open_failed', self.source)
if 'Server returned 403 Forbidden' in msg: """
if 'Server returned 4' in msg:
self.dispatch('on_open_failed', self.source)
if 'Server returned 5' in msg:
self.dispatch('on_open_failed', self.source) self.dispatch('on_open_failed', self.source)
msg = msg.strip() msg = msg.strip()
@ -52,6 +69,15 @@ class NewVideo(BGColorBehavior, Video):
def on_state(self,*args): def on_state(self,*args):
super().on_state(*args) super().on_state(*args)
if self.state == 'play': if self.state == 'play':
if self.load_status == 'start':
self.load_status = 'success'
t = time.time()
self.dispatch('on_load_success',
{
'source':self.source,
'time':int((t - self.start_time)*100)
})
Window.allow_screensaver = False Window.allow_screensaver = False
else: else:
Window.allow_screensaver = True Window.allow_screensaver = True

View File

@ -95,7 +95,7 @@ class Toolbar(BoxLayout):
items_desc=subs_desc, items_desc=subs_desc,
orientation=opts.get('orientation','horizontal') orientation=opts.get('orientation','horizontal')
) )
for ti in self.toggle_items.children: for ti in self.toggle_items.item_widgets:
ti.widget_id = ti.user_data ti.widget_id = ti.user_data
self.toggle_items.bind(on_press=self.tool_press) self.toggle_items.bind(on_press=self.tool_press)
self.add_widget(self.toggle_items) self.add_widget(self.toggle_items)
@ -169,7 +169,7 @@ class ToolPage(BGColorBehavior, BoxLayout):
'toggleitems=',self.toolbar.toggle_items.width, \ 'toggleitems=',self.toolbar.toggle_items.width, \
self.toolbar.toggle_items.height) self.toolbar.toggle_items.height)
toggle_items = self.toolbar.toggle_items toggle_items = self.toolbar.toggle_items
for c in toggle_items.children: for c in toggle_items.item_widgets:
cvalue = c.getValue() cvalue = c.getValue()
if cvalue == self.show_name: if cvalue == self.show_name:
c.dispatch('on_press') c.dispatch('on_press')
@ -214,7 +214,7 @@ class ToolPage(BGColorBehavior, BoxLayout):
self.add_widget(self.content) self.add_widget(self.content)
self.add_widget(self.toolbar) self.add_widget(self.toolbar)
toggle_items = self.toolbar.toggle_items toggle_items = self.toolbar.toggle_items
for t in toggle_items.children: for t in toggle_items.item_widgets:
t.bind(on_press=self.on_press_handle) t.bind(on_press=self.on_press_handle)
def get_tool_by_name(self,name): def get_tool_by_name(self,name):
@ -241,6 +241,7 @@ class ToolPage(BGColorBehavior, BoxLayout):
if w is None or t.fresh: if w is None or t.fresh:
if t.url: if t.url:
w = self.build_widget(t.url) w = self.build_widget(t.url)
if w:
self.content_widgets[name] = w self.content_widgets[name] = w
self.content.add_widget(w) self.content.add_widget(w)
return return

View File

@ -1,4 +1,5 @@
from kivy.uix.scrollview import ScrollView from kivy.uix.scrollview import ScrollView
from kivy.effects.scroll import ScrollEffect
from kivy.uix.gridlayout import GridLayout from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Color, Ellipse,Rectangle from kivy.graphics import Color, Ellipse,Rectangle
@ -6,6 +7,7 @@ from kivy.graphics import Color, Ellipse,Rectangle
class ScrollWidget(ScrollView): class ScrollWidget(ScrollView):
def __init__(self,**kw): def __init__(self,**kw):
super(ScrollWidget,self).__init__(**kw) super(ScrollWidget,self).__init__(**kw)
self.effect_cls = ScrollEffect
self.sized_widgets = [] self.sized_widgets = []
self._inner = BoxLayout(orientation='vertical',padding=5, self._inner = BoxLayout(orientation='vertical',padding=5,
spacing=8,size_hint=(None,None)) spacing=8,size_hint=(None,None))