diff --git a/README.md b/README.md index 36879b9..a8bed30 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,78 @@ # KivyBlocks -Can you ever image build a gui application like play Lego blocks? kivyblocks it try to provide programmer a tool to build a application +Can you ever image build a gui application like play Lego blocks? kivyblocks just try to provide programmer a tool to build a application like play lego blocks + +kivyblocks base on the python package 'kivy', which is a cross platform GUI package and can play on window, linux, mac OS x, android and iphone ## Requirement + +[appPublic](https://github.com/yumoqing/appPublic) +[kivycalendar](https://github.com/yumoqing/kivycalendar) +[kivy](https://github.com/kivy/kivy) +... see the [requirements.txt]('./requirements.txt') ## Principle -There is a blocksapp(inherited from App) contains a toppage widget to hold all the top widget create by Blocks, and the Blocks can create widgets which is specified in a dictionary data, and a HttpClient to get data or weiget spec file for web server. +There is a BlocksApp(inherited from App) in kivyblocks contains a all widgets can be created by Blocks, and the Blocks creates widgets according a customized json data, the data can download from application server or local filesystem. +The Customized json data has it own format to descript the UI and it's interaction. please see the "Customized json data" section for further information. -the widget specifiction file +## installation +``` +pip install git+https://github.com/yumoqing/kivy-blocks +``` +Use above command to install the newest version of kivyblocks +the widget specification file ## How to use see the simple example below: ``` -``` +import sys +import os +from appPublic.folderUtils import ProgramPath +from appPublic.jsonConfig import getConfig + +from kivyblocks.blocksapp import BlocksApp +from kivyblocks.blocks import Blocks + +class TestApp(BlocksApp): + def build(self): + b = super(TestApp, self).build() + widget_desc = { + "widgettype":"VBox", + "options":{}, + "subwidgets":[ + { + "widgettype":"Title1", + "options":{ + "text":"Say Hello", + "i18n":True, + "size_hint_y":None, + "height":"py::CSize(2)" + } + }, + { + "widgettype":"Text", + "options":{ + "text":"Hello KivyBlocks" + } + } + ] + } + blocks = Blocks() + x = blocks.widgetBuild(widget_desc) + return x + + +if __name__ == '__main__': + pp = ProgramPath() + workdir = pp + if len(sys.argv) > 1: + workdir = sys.argv[1] + print('ProgramPath=',pp,'workdir=',workdir) + + config = getConfig(workdir,NS={'workdir':workdir,'ProgramPath':pp}) + myapp = TestApp() + myapp.run() +``` +if you running it on window, it will show the following: +![hello](./docs/imgs/hello_window.png) diff --git a/docs/blocks.md b/docs/blocks.md new file mode 100644 index 0000000..0668666 --- /dev/null +++ b/docs/blocks.md @@ -0,0 +1,47 @@ +# Blocks +Blocks是kivyblocks的核心类,负责将字典类型的数据转化为GUI的Widget。 +Blocks也注册到了kivy.factory.Factory中,可以使用 +``` +blocks = Factory.Blocks() +``` +初始化实例 + +## 方法 +### widgetBuild(desc) +#### 参数 +* desc 1) 字典类型, Widget描述的字典数据 + 2) 字符串,可通过json导入的字符串 + +#### 返回值 +成功返回创建的widget实例 +失败返回空 + +#### 事件 +如果创建widget成功,触发”on_built"事件, +如果创建widget失败,将触发“on_failed”事件 + +事件处理函数的例子如下: +创建成功: +``` +def on_built(o, w): + pass +``` +其中,o为Blocks实例, w为新建widget的实例 +创建失败 +``` +def on_failed(o,e): + pass +``` +其中, o为Blocks实例, e为例外实例 + +#### 功能描述 +此方法按照desc字典数据构建一个Widget,首先按照desc['options']中的参数初始化“widgettype”属性指定的类,并将“subwidgets”中的子Widget创建,并添加到Widget中,并且将非“options”,“subwidgets“和”binds“的其他属性也创建完成,并作为Widget的属性变量,最后创建”binds“中的事件处理。 + +widgetBuild按照执行结果的状态,会触发两个事件中的一个,如果创建成功,会触发"on_built" + +### getWidgetById(id, from_widget=None) +查找指定id的widget,可以指定从整个widget树上的哪个节点开始查找。 +#### 参数 +id:字符串,其中‘.'用于分割,节点id,如果id中存在‘.',那么 +## 使用用例 + diff --git a/docs/imgs/hello_window.png b/docs/imgs/hello_window.png new file mode 100644 index 0000000..9ce13a8 Binary files /dev/null and b/docs/imgs/hello_window.png differ diff --git a/kivyblocks/blocksapp.py b/kivyblocks/blocksapp.py index 40261c5..cdb4a90 100644 --- a/kivyblocks/blocksapp.py +++ b/kivyblocks/blocksapp.py @@ -91,13 +91,14 @@ class BlocksApp(App): self.workers = Workers(maxworkers=config.maxworkers or 80) self.workers.start() self.running = True - blocks = Blocks() - print(config.root) - x = blocks.widgetBuild(config.root) - if x is None: - alert('buildError,Exit', title='Error') - return Label(text='error') - return x + if config.root: + blocks = Blocks() + x = blocks.widgetBuild(config.root) + if x is None: + alert('buildError,Exit', title='Error') + return Label(text='error') + return x + return None def realurl(self, url): if url.startswith('https://') or url.startswith('http://'): diff --git a/kivyblocks/i18n.py b/kivyblocks/i18n.py index 1293c5e..38db754 100644 --- a/kivyblocks/i18n.py +++ b/kivyblocks/i18n.py @@ -38,15 +38,17 @@ class I18n: def loadI18n(self,lang): app = App.get_running_app() config = getConfig() + self.kvlang[lang] = {} if config.i18n_folder: self.kvlang[lang] = self.loadI18nFromFolder(lang) return - url = '%s%s/%s' % (config.uihome, config.i18n_url, lang) - hc = HttpClient() - d = hc.get(url) - print('i18n() %s get data=' % url, d, type(d)) - self.kvlang[lang] = d + if config.i18n_url: + url = '%s%s/%s' % (config.uihome, config.i18n_url, lang) + hc = HttpClient() + d = hc.get(url) + print('i18n() %s get data=' % url, d, type(d)) + self.kvlang[lang] = d def __call__(self,msg,lang=None): if lang is None: diff --git a/test/conf/config.json b/test/conf/config.json index ce22fb4..a7bbcfc 100644 --- a/test/conf/config.json +++ b/test/conf/config.json @@ -7,18 +7,5 @@ "huge":5.5, "hugest":6.5 }, - "font_name":"normal", - "uihome":"http://www.bsppo.com:10080", - "i18n_url":"/public/i18n", - "publickey_url":"/public/publickey", - "login_url":"/public/publickey", - "udws":[ - "/udw/udws.uidesc" - ], - "root":{ - "widgettype":"urlwidget", - "options":{ - "url":"/test/loginform.ui" - } - } + "font_name":"normal" } diff --git a/test/main.py b/test/main.py index b971563..e9b7b7d 100644 --- a/test/main.py +++ b/test/main.py @@ -4,6 +4,36 @@ from appPublic.folderUtils import ProgramPath from appPublic.jsonConfig import getConfig from kivyblocks.blocksapp import BlocksApp +from kivyblocks.blocks import Blocks + +class TestApp(BlocksApp): + def build(self): + b = super(TestApp, self).build() + widget_desc = { + "widgettype":"VBox", + "options":{}, + "subwidgets":[ + { + "widgettype":"Title1", + "options":{ + "text":"Say Hello", + "i18n":True, + "size_hint_y":None, + "height":"py::CSize(2)" + } + }, + { + "widgettype":"Text", + "options":{ + "text":"Hello KivyBlocks" + } + } + ] + } + blocks = Blocks() + x = blocks.widgetBuild(widget_desc) + return x + if __name__ == '__main__': pp = ProgramPath() @@ -13,7 +43,6 @@ if __name__ == '__main__': print('ProgramPath=',pp,'workdir=',workdir) config = getConfig(workdir,NS={'workdir':workdir,'ProgramPath':pp}) - myapp = BlocksApp() + myapp = TestApp() myapp.run() - myapp.workers.running = False