This commit is contained in:
yumoqing 2021-03-16 11:11:15 +08:00
parent d2e9358624
commit 00446d7500
7 changed files with 160 additions and 32 deletions

View File

@ -1,16 +1,78 @@
# KivyBlocks # 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 ## 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') see the [requirements.txt]('./requirements.txt')
## Principle ## 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 ## How to use
see the simple example below: 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)

47
docs/blocks.md Normal file
View File

@ -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中存在.',那么
## 使用用例

BIN
docs/imgs/hello_window.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -91,13 +91,14 @@ class BlocksApp(App):
self.workers = Workers(maxworkers=config.maxworkers or 80) self.workers = Workers(maxworkers=config.maxworkers or 80)
self.workers.start() self.workers.start()
self.running = True self.running = True
blocks = Blocks() if config.root:
print(config.root) blocks = Blocks()
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')
return Label(text='error') return Label(text='error')
return x return x
return None
def realurl(self, url): def realurl(self, url):
if url.startswith('https://') or url.startswith('http://'): if url.startswith('https://') or url.startswith('http://'):

View File

@ -38,15 +38,17 @@ class I18n:
def loadI18n(self,lang): def loadI18n(self,lang):
app = App.get_running_app() app = App.get_running_app()
config = getConfig() config = getConfig()
self.kvlang[lang] = {}
if config.i18n_folder: if config.i18n_folder:
self.kvlang[lang] = self.loadI18nFromFolder(lang) self.kvlang[lang] = self.loadI18nFromFolder(lang)
return return
url = '%s%s/%s' % (config.uihome, config.i18n_url, lang) if config.i18n_url:
hc = HttpClient() url = '%s%s/%s' % (config.uihome, config.i18n_url, lang)
d = hc.get(url) hc = HttpClient()
print('i18n() %s get data=' % url, d, type(d)) d = hc.get(url)
self.kvlang[lang] = d print('i18n() %s get data=' % url, d, type(d))
self.kvlang[lang] = d
def __call__(self,msg,lang=None): def __call__(self,msg,lang=None):
if lang is None: if lang is None:

View File

@ -7,18 +7,5 @@
"huge":5.5, "huge":5.5,
"hugest":6.5 "hugest":6.5
}, },
"font_name":"normal", "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"
}
}
} }

View File

@ -4,6 +4,36 @@ from appPublic.folderUtils import ProgramPath
from appPublic.jsonConfig import getConfig from appPublic.jsonConfig import getConfig
from kivyblocks.blocksapp import BlocksApp 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__': if __name__ == '__main__':
pp = ProgramPath() pp = ProgramPath()
@ -13,7 +43,6 @@ if __name__ == '__main__':
print('ProgramPath=',pp,'workdir=',workdir) print('ProgramPath=',pp,'workdir=',workdir)
config = getConfig(workdir,NS={'workdir':workdir,'ProgramPath':pp}) config = getConfig(workdir,NS={'workdir':workdir,'ProgramPath':pp})
myapp = BlocksApp() myapp = TestApp()
myapp.run() myapp.run()
myapp.workers.running = False