bugfix
This commit is contained in:
parent
d2e9358624
commit
00446d7500
70
README.md
70
README.md
@ -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
47
docs/blocks.md
Normal 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
BIN
docs/imgs/hello_window.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -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://'):
|
||||||
|
@ -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:
|
||||||
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
33
test/main.py
33
test/main.py
@ -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
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user