diff --git a/kivyblocks/baseWidget.py b/kivyblocks/baseWidget.py index 6592407..eb79f91 100755 --- a/kivyblocks/baseWidget.py +++ b/kivyblocks/baseWidget.py @@ -70,7 +70,6 @@ from .bgcolorbehavior import BGColorBehavior from .utils import NeedLogin, InsufficientPrivilege, HTTPError from .login import LoginForm from .tab import TabsPanel -from .qrdata import QRCodeWidget from .threadcall import HttpClient from .i18n import I18n from .widget_css import WidgetCSS @@ -211,11 +210,21 @@ class Title6(Text): Text.__init__(self, **kw) class Modal(ModalView): - def __init__(self, auto_open=False, **kw): + def __init__(self, auto_open=False, + content=None, + **kw): ModalView.__init__(self, **kw) self.auto_open = auto_open + if content: + blocks = Factory.Blocks() + self.content = blocks.widgetBuild(content) + if self.content: + self.add_widget(self.content) + else: + print(content,':cannot build widget') + - def add_widget(self,w, *args, **kw): + def add_widget(self, w, *args, **kw): super().add_widget(w, *args, **kw) if self.auto_open: self.open() diff --git a/kivyblocks/blocks.py b/kivyblocks/blocks.py index c44e18b..190ca1f 100755 --- a/kivyblocks/blocks.py +++ b/kivyblocks/blocks.py @@ -33,7 +33,6 @@ from .form import InputBox, Form, StrSearchForm from .boxViewer import BoxViewer from .tree import Tree, TextTree from .newvideo import Video -from .ready import WidgetReady from .bgcolorbehavior import BGColorBehavior from .orientationlayout import OrientationLayout from .threadcall import HttpClient @@ -42,32 +41,6 @@ from .register import * def showError(e): print('error',e) - -def wrap_ready(klass): - try: - w = Factory.get(klass) - if hasattr(w,'ready'): - return w - Factory.unregister(klass) - globals()[klass] = w - except: - print_exc() - w = globals().get(klass) - if w is None: - return None - if hasattr(w,'ready'): - return w - - script = f"""class R_{klass}(WidgetReady, {klass}): - def __init__(self, **kw): - {klass}.__init__(self, **kw) - WidgetReady.__init__(self) -""" - exec(script,globals(),globals()) - newWidget = globals().get(f'R_{klass}') - Factory.register(klass,newWidget) - return newWidget - class WidgetNotFoundById(Exception): def __init__(self, id): super().__init__() @@ -304,10 +277,10 @@ class Blocks(EventDispatcher): opts = self.valueExpr(desc.get('options',{}).copy()) widget = None try: - klass = wrap_ready(widgetClass) + klass = Factory.get(widgetClass) widget = klass(**opts) except Exception as e: - print('Error:',widgetClass,'not registered') + print('Error:',widgetClass,'contructon error') print_exc() raise NotExistsObject(widgetClass) @@ -599,16 +572,16 @@ class Blocks(EventDispatcher): try: widget = self.w_build(desc) self.dispatch('on_built',widget) - if hasattr(widget,'ready'): - widget.ready = True return widget except Exception as e: print_exc() self.dispatch('on_failed',e) return None - if not (isinstance(desc, DictObject) or isinstance(desc, dict)): - print('Block: desc must be a dict object', + if isinstance(desc,DictObject): + desc = desc.to_dict() + if not isinstance(desc, dict): + print('widgetBuild1: desc must be a dict object', desc,type(desc)) self.dispatch('on_failed',Exception('miss url')) return @@ -630,7 +603,7 @@ class Blocks(EventDispatcher): desc = self.getUrlData(url,**opts) if not (isinstance(desc, DictObject) or \ isinstance(desc, dict)): - print('Block: desc must be a dict object', + print('Block2: desc must be a dict object', desc,type(desc)) self.dispatch('on_failed',Exception('miss url')) return @@ -639,8 +612,7 @@ class Blocks(EventDispatcher): desc = dictExtend(desc,addon) widgettype = desc.get('widgettype') if widgettype is None: - print('Block: desc must be a dict object', - desc,type(desc)) + print('Block3: desc must be a dict object not None') return None return doit(desc) diff --git a/kivyblocks/blocksapp.py b/kivyblocks/blocksapp.py index 838f070..e9cf437 100644 --- a/kivyblocks/blocksapp.py +++ b/kivyblocks/blocksapp.py @@ -111,6 +111,9 @@ class BlocksApp(App): self.buildCsses(d) Logger.info('blocksapp: csses=%s', self.csses) + def get_css(self, cssname): + return self.csses.get(cssname, 'default') + def on_rotate(self,*largs): self.current_rotation = Window.rotation Logger.info('BlocksApp:on_rotate(), largs=%s', @@ -140,8 +143,8 @@ class BlocksApp(App): "fgcolor":[0.85,0.85,0.85,1] }, "input_focus":{ - "bgcolor":[1,0.35,0.35,1], - "fgcolor":[1,0.85,0.85,1] + "bgcolor":[0.25,0.25,0.25,1], + "fgcolor":[0.8,0.8,0.8,1] } } self.public_headers = {} diff --git a/kivyblocks/custom_camera.py b/kivyblocks/custom_camera.py index 74dc7c4..30f7766 100644 --- a/kivyblocks/custom_camera.py +++ b/kivyblocks/custom_camera.py @@ -87,4 +87,8 @@ class QrReader(XCamera): self.dispatch('on_data',self.qr_result) super(QrReader, self).on_tex(self.texture) + def dismiss(self, *args, **kw): + self.release() + cv2.destroyAllWindows() + Builder.load_string(btxt) diff --git a/kivyblocks/dataloader.py b/kivyblocks/dataloader.py index 8cb697a..e43d862 100644 --- a/kivyblocks/dataloader.py +++ b/kivyblocks/dataloader.py @@ -1,6 +1,7 @@ from kivy.event import EventDispatcher from kivy.app import App +from kivy.factory import Factory from .threadcall import HttpClient from .utils import absurl from appPublic.registerfunction import RegisterFunction @@ -47,8 +48,9 @@ class DataGraber(EventDispatcher): ret = self.loadRFData(*args, **kw) break target = self.options.get('datatarget') - ret = self.loadTargetData(*args, **kw) - break + if target: + ret = self.loadTargetData(*args, **kw) + break except Exception as e: self.dispatch('on_error', e) return diff --git a/kivyblocks/form.py b/kivyblocks/form.py index 35d092b..536c4a7 100644 --- a/kivyblocks/form.py +++ b/kivyblocks/form.py @@ -13,9 +13,9 @@ from .utils import * 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 +from .widget_css import WidgetCSS """ form options @@ -164,8 +164,6 @@ class InputBox(BoxLayout): opts['size_hint_x'] = None opts['width'] = self.labelwidth bl = BoxLayout(**opts) - Logger.info('kivyblock:labelwidth=%f,opts=%s', self.labelwidth,str(opts)) - Logger.info('kivyblock:bl.widht=%f,bl.height=%f',bl.width,bl.height) self.add_widget(bl) label = self.options.get('label',self.options.get('name')) kwargs = { @@ -175,8 +173,6 @@ class InputBox(BoxLayout): } self.labeltext = Text(**kwargs) bl.add_widget(self.labeltext) - Logger.info('kivyblock:label.widht=%f,label.height=%f', - self.labeltext.width,self.labeltext.height) if self.options.get('required',False): star = Label(text='*', color=(1,0,0,1), @@ -188,6 +184,7 @@ class InputBox(BoxLayout): options['allow_copy'] = True options['width'] = options.get('width',1) options['height'] = options.get('height',1) + options['csscls'] = self.form.input_css if self.options.get('hint_text'): options['hint_text'] = i18n(self.options.get('hint_text')) @@ -260,11 +257,11 @@ def defaultToolbar(): } -class Form(BGColorBehavior, WidgetReady, BoxLayout): +class Form(WidgetCSS, WidgetReady, BoxLayout): def __init__(self, - color_level=1, - radius=[], - cols=2, + cols=1, + csscls='default', + input_css='input', inputwidth=0, inputheight=3, labelwidth=0.3, @@ -277,6 +274,7 @@ class Form(BGColorBehavior, WidgetReady, BoxLayout): toolbar={}, **options): self.inputwidth = 1 + self.input_css = input_css self.inputheight = inputheight self.labelwidth= labelwidth self.fields = fields @@ -291,12 +289,12 @@ class Form(BGColorBehavior, WidgetReady, BoxLayout): 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) + print('options=', options) + super(Form, self).__init__(**options) + #BoxLayout.__init__(self, **options) + #WidgetReady.__init__(self) + #WidgetCSS.__init__(self) + self.csscls = csscls self.cols = self.options_cols = cols if isHandHold() and Window.width < Window.height: self.cols = 1 @@ -450,14 +448,18 @@ class StrSearchForm(BoxLayout): def __init__(self,img_url=None,**options): self.name = options.get('name','search_string') BoxLayout.__init__(self,orientation='horizontal',size_hint_y=None,height=CSize(3)) + self.input_css = options.get('input_css', 'input') + i18n = I18n() self.input_widget = StrInput( text='', multiline=False, + csscls=self.input_css, + hint_text=i18n(options.get('tip',options.get('hint_text',''))), allow_copy=True, - font_size=1, + font_size=CSize(1), size_hint_y=None, size_hint_x=1, - height=2) + height=3) self.add_widget(self.input_widget) self.register_event_type('on_submit') v = options.get('value',options.get('default_value','')) diff --git a/kivyblocks/newvideo.py b/kivyblocks/newvideo.py index 09bd84b..ec6bedb 100644 --- a/kivyblocks/newvideo.py +++ b/kivyblocks/newvideo.py @@ -8,20 +8,16 @@ from kivy.clock import Clock from ffpyplayer.tools import set_log_callback -from kivyblocks.bgcolorbehavior import BGColorBehavior logger_func = {'quiet': Logger.critical, 'panic': Logger.critical, 'fatal': Logger.critical, 'error': Logger.error, 'warning': Logger.warning, 'info': Logger.info, 'verbose': Logger.debug, 'debug': Logger.debug} -class NewVideo(BGColorBehavior, Video): +class NewVideo(Video): center_screen = BooleanProperty(False) - def __init__(self,color_level=-1,radius=[],**kw): + def __init__(self, **kw): Video.__init__(self, **kw) - BGColorBehavior.__init__(self, - color_level=color_level, - radius=radius) Window.allow_screensaver = False set_log_callback(self.ffplayerLog) self.register_event_type('on_open_failed') diff --git a/kivyblocks/qrcodereader.py b/kivyblocks/qrcodereader.py index cb99aaa..3abc74c 100644 --- a/kivyblocks/qrcodereader.py +++ b/kivyblocks/qrcodereader.py @@ -32,7 +32,7 @@ class QRCodeReader(Image): self.dismiss() super().on_touch_down(touch) - def dismiss(self): + def dismiss(self, *args, **kw): if not self.opened: return self.opened = False @@ -54,7 +54,10 @@ class QRCodeReader(Image): self.showImage(img) data,bbox,_ = self.detector.detectAndDecode(img) if data: - self.dispatch('on_data',data) + d = { + 'data':data + } + self.dispatch('on_data',d) if __name__ == '__main__': class MyApp(App): diff --git a/kivyblocks/qrdata.py b/kivyblocks/qrdata.py index c63df84..1b3f591 100644 --- a/kivyblocks/qrdata.py +++ b/kivyblocks/qrdata.py @@ -13,9 +13,11 @@ from kivy.properties import ObjectProperty, StringProperty, ListProperty,\ BooleanProperty from kivy.lang import Builder from kivy.clock import Clock + +from .baseWidget import VBox import qrcode -class QRCodeWidget(FloatLayout): +class QRCodeWidget(VBox): data = StringProperty(None, allow_none=True) ''' Data using which the qrcode is generated. @@ -31,13 +33,12 @@ class QRCodeWidget(FloatLayout): ''' def __init__(self, **kwargs): - self.qrimage = Image(allow_stretch=True) + self.qrimage = Image(allow_stretch=True, keep_ratio=True) self.addr = None super(QRCodeWidget, self).__init__(**kwargs) self.background_color = [1,1,1,1] self.qr = None self._qrtexture = None - self.qrimage.pos_hint = {'center_x':0.5, 'center_y':0.5} self.add_widget(self.qrimage) def on_size(self,o,s): @@ -60,7 +61,7 @@ class QRCodeWidget(FloatLayout): def set_addr(self, addr): if self.addr == addr: return - MinSize = 210 if len(addr) < 128 else 500 + MinSize = 500 #210 if len(addr) < 128 else 500 self.setMinimumSize((MinSize, MinSize)) self.addr = addr self.qr = None @@ -76,7 +77,7 @@ class QRCodeWidget(FloatLayout): version=None, error_correction=L, box_size=10, - border=0, + border=4, ) qr.add_data(addr) qr.make(fit=True) diff --git a/kivyblocks/register.py b/kivyblocks/register.py index a4619ae..7c3b942 100644 --- a/kivyblocks/register.py +++ b/kivyblocks/register.py @@ -1,5 +1,6 @@ import kivy from kivy.utils import platform +from kivy.uix.textinput import TextInput from appPublic.registerfunction import RegisterFunction @@ -35,6 +36,7 @@ from .camerawithmic import CameraWithMic r = Factory.register if kivy.platform in ['win','linux', 'macosx']: r('ScreenWithMic', ScreenWithMic) +r('TextInput', TextInput) r('CameraWithMic', CameraWithMic) r('CustomCamera', CustomCamera) r('QrReader', QrReader) diff --git a/kivyblocks/widgetExt/inputext.py b/kivyblocks/widgetExt/inputext.py index 63153d0..914ebc2 100755 --- a/kivyblocks/widgetExt/inputext.py +++ b/kivyblocks/widgetExt/inputext.py @@ -1,5 +1,6 @@ import sys import re +from kivy.app import App from kivy.logger import Logger from kivy.uix.image import Image from kivy.uix.boxlayout import BoxLayout @@ -16,7 +17,7 @@ from ..utils import CSize from ..widget_css import WidgetCSS class BoolInput(Switch): - def __init__(self,**kw): + def __init__(self,csscls='input', **kw): a = DictObject() if kw.get('defaultvalue',None) is None: a.active = False @@ -41,20 +42,26 @@ class BoolInput(Switch): def setValue(self,v): self.active = v -class StrInput(WidgetCSS, TextInput): - def __init__(self,**kv): +class StrInput(TextInput): + def __init__(self,csscls='default', + **kv): if kv is None: kv = {} + app = App.get_running_app() + css = app.get_css(csscls) a = { "allow_copy":True, "password":False, "multiline":False, "halign":"left", - "hint_text":"", + "hint_text":"test", "text_language":"zh_CN", + "font_size":CSize(1), "write_tab":False } a.update(kv) + a['background_color'] = css['bgcolor'] + a['foreground_color'] = css['fgcolor'] w = kv.get('width',1) h = kv.get('height',1) if w <= 1: @@ -67,13 +74,11 @@ class StrInput(WidgetCSS, TextInput): else: a['size_hint_y'] = None a['height'] = CSize(h) - a['font_size'] = CSize(kv.get('font_size',0.9)) - Logger.info('TextInput:a=%s,kv=%s',a,kv) + Logger.info('StrInput:a=%s,kv=%s',a,kv) super(StrInput, self).__init__(**a) self.old_value = None self.register_event_type('on_changed') - self.bind(focus=self.on_focus) self.bind(on_text_validate=self.checkChange) def on_changed(self,v=None): @@ -84,14 +89,6 @@ class StrInput(WidgetCSS, TextInput): if v != self.old_value: self.dispatch('on_changed',v) - def on_focus(self,t,v): - if v: - self.old_value = self.getValue() - self.csscls = 'input_focus' - else: - self.checkChange(None) - self.csscls = 'input' - def getValue(self): return self.text @@ -156,7 +153,7 @@ class AmountInput(FloatInput): return StrInput.insert_text(self,s, from_undo=from_undo) class MyDropDown(DropDown): - def __init__(self,**kw): + def __init__(self,csscls='input', **kw): super(MyDropDown,self).__init__() self.options = kw self.textField = kw.get('textField','text') @@ -221,7 +218,7 @@ class MyDropDown(DropDown): self.open(w) class SelectInput(BoxLayout): - def __init__(self,**kw): + def __init__(self,csscls='input', **kw): a={} w = kw.get('width',10) h = kw.get('height',1.5) diff --git a/kivyblocks/widgetExt/messager.py b/kivyblocks/widgetExt/messager.py index b07582c..fc32852 100644 --- a/kivyblocks/widgetExt/messager.py +++ b/kivyblocks/widgetExt/messager.py @@ -3,10 +3,6 @@ from kivy.clock import Clock from kivy.uix.boxlayout import BoxLayout from kivy.uix.textinput import TextInput from ..widget_css import WidgetCSS -class MyPopup(WidgetCSS, Popup): - def __init__(self,content=None, title='', **kw): - super(MyPopup, self).__init__(content=content, - title=title, **kw) class Messager: def __init__(self, show_time=0, title=None, **kw): @@ -17,6 +13,8 @@ class Messager: title=self.title, size_hint=(0.8,0.8), **kw) self.messager = TextInput(size=self.w.content.size, + background_color=[0.9,0.9,0.9,1], + foreground_color=[0.3,0.3,0.3,1], multiline=True,readonly=True) self.w.content.add_widget(self.messager) diff --git a/kivyblocks/widget_css.py b/kivyblocks/widget_css.py index 29cfe30..5a6083b 100644 --- a/kivyblocks/widget_css.py +++ b/kivyblocks/widget_css.py @@ -120,9 +120,9 @@ class WidgetCSS(object): def on_radius(self, o, r): if not self.radius: self.bg_func = Rectangle - return - self.bg_func = RoundedRectangle - # self.set_background_color() + else: + self.bg_func = RoundedRectangle + self.set_background_color() def set_background_color(self, *args): if not self.bgcolor: