bugfix
This commit is contained in:
parent
72b46d5078
commit
9f93b18a8f
14
py/iptv/ui/cbs_news.ui
Normal file
14
py/iptv/ui/cbs_news.ui
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"NewVideo",
|
||||||
|
"id":"vplayer",
|
||||||
|
"options":{
|
||||||
|
"h_pattern":{
|
||||||
|
"iptv.bsppo.com":"referer:https://github.com",
|
||||||
|
"alicloudccp.com":"referer:https://www.aliyundrive.com/"
|
||||||
|
},
|
||||||
|
"source":"https://cbsn-us.cbsnstream.cbsnews.com/out/v1/55a8648e8f134e82a470f83d562deeca/master.m3u8",
|
||||||
|
"allow_stretch":true,
|
||||||
|
"keep_ratio":true,
|
||||||
|
"play":true
|
||||||
|
}
|
||||||
|
}
|
25
py/iptv/ui/channel_box.ui
Normal file
25
py/iptv/ui/channel_box.ui
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"VBox",
|
||||||
|
"options":{
|
||||||
|
"size_hint":[0.5, None],
|
||||||
|
"height":300
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"Text",
|
||||||
|
"options":{
|
||||||
|
"size_hint":[1,1],
|
||||||
|
"text":"{{params_kw['tv_name']}}",
|
||||||
|
"wrap":true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype":"Text",
|
||||||
|
"options":{
|
||||||
|
"size_hint":[1,1],
|
||||||
|
"text":"{{params_kw['channel_delay']}}",
|
||||||
|
"wrap":true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
31
py/iptv/ui/channel_list.ui
Normal file
31
py/iptv/ui/channel_list.ui
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"id":"channel_list",
|
||||||
|
"widgettype":"HBox",
|
||||||
|
"options":{
|
||||||
|
"size_hint":[1,1]
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('./channels_show.ui')}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"vplayer",
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('./video.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"search_result",
|
||||||
|
"event":"on_selected",
|
||||||
|
"actiontype":"script",
|
||||||
|
"target":"vplayer",
|
||||||
|
"script":"self.set_source(args[1].row_data['url'])"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
17
py/iptv/ui/channel_search.dspy
Normal file
17
py/iptv/ui/channel_search.dspy
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
async def get_channels(ns):
|
||||||
|
sql = "select * from iptvchannels where 1=1 "
|
||||||
|
if ns.get('search_string') and ns['search_string'] != "":
|
||||||
|
search_string = ns.get('search_string')
|
||||||
|
sql = "%s and tv_name like '%%%%%s%%%%'" % (sql, search_string)
|
||||||
|
rec = await runSQLPaging('iptvdb',sql,ns=ns)
|
||||||
|
return rec
|
||||||
|
|
||||||
|
ns = await request2ns()
|
||||||
|
print('ns=',ns)
|
||||||
|
ns['sort'] = 'tv_name'
|
||||||
|
if not ns.get('page'):
|
||||||
|
ns['page'] = 1
|
||||||
|
if not ns.get('userid'):
|
||||||
|
ns['userid'] = 'Anoumous'
|
||||||
|
ret = await get_channels(ns)
|
||||||
|
return ret
|
23
py/iptv/ui/channels.ui
Normal file
23
py/iptv/ui/channels.ui
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"BoxViewer",
|
||||||
|
"options":{
|
||||||
|
"dataloader":{
|
||||||
|
"widgettype":"RelatedLoader",
|
||||||
|
"options":{
|
||||||
|
"page_rows":60,
|
||||||
|
"dataurl":"{{entire_url('get_channels.dspy')}}",
|
||||||
|
"params":{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"boxwidth":14,
|
||||||
|
"boxheight":8,
|
||||||
|
"viewer":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('channel_box.ui')}}",
|
||||||
|
"params":{{json.dumps(params_kw)}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
py/iptv/ui/channels_show.ui
Normal file
50
py/iptv/ui/channels_show.ui
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"VBox",
|
||||||
|
"id":"channels_show",
|
||||||
|
"options":{
|
||||||
|
"size_hint_y":1,
|
||||||
|
"size_hint_x":0.3
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"id":"search_key",
|
||||||
|
"widgettype":"Form",
|
||||||
|
"options":{
|
||||||
|
"size_hint_y":null,
|
||||||
|
"height":100,
|
||||||
|
"notoolbar":true,
|
||||||
|
"size_hint_y":null,
|
||||||
|
"height":"py::CSize(2.4)",
|
||||||
|
"inputwidth":23,
|
||||||
|
"labelwidth":0.3,
|
||||||
|
"inputheight":2,
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"name":"search_string",
|
||||||
|
"datatype":"str",
|
||||||
|
"uitype":"str",
|
||||||
|
"label":"搜索",
|
||||||
|
"uitype":"str"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"search_result",
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url":"{{entire_url('show_channels.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"search_key.search_string",
|
||||||
|
"event":"on_changed",
|
||||||
|
"actiontype":"method",
|
||||||
|
"datawidget":"search_key",
|
||||||
|
"target":"search_result",
|
||||||
|
"method":"loadData"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
6
py/iptv/ui/cloudpc.ui
Normal file
6
py/iptv/ui/cloudpc.ui
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"Label",
|
||||||
|
"options":{
|
||||||
|
"text":"测试内容"
|
||||||
|
}
|
||||||
|
}
|
2
py/iptv/ui/csses.json
Normal file
2
py/iptv/ui/csses.json
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
3
py/iptv/ui/get_channels.dspy
Normal file
3
py/iptv/ui/get_channels.dspy
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
prog = 'get_channels.dspy'
|
||||||
|
db = DBPools()
|
||||||
|
|
53
py/iptv/ui/index.ui
Normal file
53
py/iptv/ui/index.ui
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"TabsPanel",
|
||||||
|
"options":{
|
||||||
|
"do_default_tab":false,
|
||||||
|
"bgcolor":"#ff7f7f",
|
||||||
|
"tab_pos":"bottom_left",
|
||||||
|
"tabs":[
|
||||||
|
{
|
||||||
|
"text":"频道",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('channel_list.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text":"视频",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('resource.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text":"我的",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('cbs_news.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"on_content_show",
|
||||||
|
"actiontype":"script",
|
||||||
|
"target":"app",
|
||||||
|
"script":"self.vplayer_play(*args)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"on_content_hide",
|
||||||
|
"actiontype":"script",
|
||||||
|
"target":"app",
|
||||||
|
"script":"self.vplayer_stop(*args)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
7
py/iptv/ui/my.ui
Normal file
7
py/iptv/ui/my.ui
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"Text",
|
||||||
|
"options":{
|
||||||
|
"i18n":true,
|
||||||
|
"otext":"我的"
|
||||||
|
}
|
||||||
|
}
|
46
py/iptv/ui/product.ui
Normal file
46
py/iptv/ui/product.ui
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"TabsPanel",
|
||||||
|
"options":{
|
||||||
|
"do_default_tab":true,
|
||||||
|
"tab_pos":"top_right",
|
||||||
|
"tabs":[
|
||||||
|
{
|
||||||
|
"text":"云主机",
|
||||||
|
"default":true,
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('cloudpc.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text":"超算产品",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('cloudpc.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text":"智算产品",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('cloudpc.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text":"网络产品",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('cloudpc.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
2
py/iptv/ui/public/i18n/en_US
Normal file
2
py/iptv/ui/public/i18n/en_US
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
6
py/iptv/ui/resource.ui
Normal file
6
py/iptv/ui/resource.ui
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"Label",
|
||||||
|
"options":{
|
||||||
|
"text":"资源"
|
||||||
|
}
|
||||||
|
}
|
46
py/iptv/ui/show_channels.ui
Normal file
46
py/iptv/ui/show_channels.ui
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"id":"search_result",
|
||||||
|
"widgettype":"Container",
|
||||||
|
"options":{
|
||||||
|
"loader":{
|
||||||
|
"dataurl":"{{entire_url('./channel_search.dspy')}}",
|
||||||
|
"rows":60
|
||||||
|
},
|
||||||
|
"idField":"id",
|
||||||
|
"do_scroll_x":false,
|
||||||
|
"layout":{
|
||||||
|
"widgettype":"VBox",
|
||||||
|
"options":{
|
||||||
|
"size_hint":[1,null]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"viewer":{
|
||||||
|
"widgettype":"PressableBoxLayout",
|
||||||
|
"options":{
|
||||||
|
"orientation":"horizontal",
|
||||||
|
"height":"40",
|
||||||
|
"size_hint_y":null
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"Text",
|
||||||
|
"options":{
|
||||||
|
"i18n":false,
|
||||||
|
"wrap":true,
|
||||||
|
"halign":"left",
|
||||||
|
"otext":"{% raw -%}{{tv_name}}{%- endraw %}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"on_press",
|
||||||
|
"actiontype":"script",
|
||||||
|
"target":"app",
|
||||||
|
"script":"{% raw -%}self.play('{{url}}'){%- endraw %}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
py/iptv/ui/ui
Symbolic link
1
py/iptv/ui/ui
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/Users/ymq/py/iptv/ui
|
13
py/iptv/ui/video.ui
Normal file
13
py/iptv/ui/video.ui
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"NewVideo",
|
||||||
|
"id":"vplayer",
|
||||||
|
"options":{
|
||||||
|
"h_pattern":{
|
||||||
|
"iptv.bsppo.com":"referer:https://github.com",
|
||||||
|
"alicloudccp.com":"referer:https://www.aliyundrive.com/"
|
||||||
|
},
|
||||||
|
"allow_stretch":true,
|
||||||
|
"keep_ratio":true,
|
||||||
|
"play":true
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
# Kivyblocks documentation
|
|
||||||
|
|
||||||
## introduction
|
|
||||||
Kivyblock is a cross platform native user interface programming tool, it base on kivy module, and provide
|
|
||||||
##
|
|
@ -1,47 +0,0 @@
|
|||||||
# 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中存在‘.',那么
|
|
||||||
## 使用用例
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
# Change log
|
|
||||||
|
|
||||||
## version 0.3.0
|
|
||||||
add script to support local .tmpl and .dspy file translation. it can build dynamic user interface without remote server.
|
|
||||||
|
|
||||||
## version 0.3.1
|
|
||||||
* uses weakref to collect all the i18n widgets in i18n.py
|
|
||||||
* show video play position
|
|
||||||
|
|
||||||
## version 0.4.5
|
|
||||||
* add Behavior handle when build Widget by blocks
|
|
||||||
* support following behaviors
|
|
||||||
1 ButtonBehavior
|
|
||||||
2 CodeNavigationBehavior
|
|
||||||
3 CompoundSelectionBehavior
|
|
||||||
4 CoverBehavior
|
|
||||||
5 DragBehavior
|
|
||||||
6 EmacsBehavior
|
|
||||||
7 FocusBehavior
|
|
||||||
8 ToggleButtonBehavior
|
|
||||||
9 TouchRippleBehavior
|
|
||||||
10 TouchRippleButtonBehavior
|
|
||||||
11 BGColorBehavior
|
|
||||||
12 ModalBehavior
|
|
||||||
13 swipeBehavior
|
|
||||||
14 videoBehavior
|
|
||||||
* DataGrid class add checkbox support
|
|
||||||
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
|||||||
# 事件绑定
|
|
||||||
在构件数据格式文件中可以用”binds“属性来为构件定义一到多个事件绑定。
|
|
||||||
|
|
||||||
事件绑定是一个数组结构的数据,每个事件绑定为当前构件(及其下属命名子构件)的任何一个事件定义处理实体
|
|
||||||
|
|
||||||
一个处理实体可以是
|
|
||||||
1. 一个构件的方法
|
|
||||||
2. 一个”urlwidget“类型的构件
|
|
||||||
3. 一个描述一个构件的构件数据
|
|
||||||
4. 一个注册函数
|
|
||||||
5. 一个python脚本
|
|
||||||
6. 某个构件的事件
|
|
||||||
7. 一个组合处理(可以是上述处理实体的组合数组)
|
|
||||||
|
|
||||||
## 名称约定
|
|
||||||
|
|
||||||
* self 当前构件
|
|
||||||
|
|
||||||
* root App.root构件
|
|
||||||
|
|
||||||
* “-”(减号)开始的名称,从当前位置查找命名的祖先构件,如果到app.root还没有找到,则返回空
|
|
||||||
|
|
||||||
* app App.get_running_app
|
|
||||||
|
|
||||||
## 事件绑定数据格式说明
|
|
||||||
|
|
||||||
### wid
|
|
||||||
事件发生所在构件,如果wid所代表的构件不存在指定的事件,此事件绑定将作废,
|
|
||||||
必选项,self为当前构件
|
|
||||||
|
|
||||||
### event
|
|
||||||
事件名称,wid和event组合就可以唯一确定一个事件
|
|
||||||
|
|
||||||
### actiontype
|
|
||||||
行动类型,分别是“blocks”、”urlwidget“、“registerfunction”,“script”、“method“、”event“和”multiple“之一。
|
|
||||||
|
|
||||||
* ”blocks“:值必须是一个符合构件数据格式要求的字典数据,用来创建一个构件。
|
|
||||||
|
|
||||||
* ”urlwidget“;值必须是一个url,从服务器下载一个构件数据格式的文件来创建构件
|
|
||||||
|
|
||||||
* ”Registerfunction“:注册函数,注册函数必须是def f(*args, **kwargs)参数格式,args[0] 为wid所代表的构件对象,如果事件带数据,则从args[1]开始。
|
|
||||||
|
|
||||||
* ”script“:python 脚本。在脚本中有两个内定变量可用: self为“target”指定的构件,args=[事件对象,s事件数据]
|
|
||||||
|
|
||||||
* ”method“:构件的方法,构件由此事件绑定的”target“属性指定,此方法必须具有*args, **kwargs格式的参数定义方式
|
|
||||||
|
|
||||||
* ”event“:构件的事件,构件由此事件绑定的”target“属性指定,事件绑定的参数将传递给此事件
|
|
||||||
|
|
||||||
* “multiple”:组合绑定,参看例子
|
|
||||||
|
|
||||||
### datatarget
|
|
||||||
指定数据获取的构件,此构件需有“getValue”方法,用来获取数据,数据需是字典类型
|
|
||||||
|
|
||||||
### target
|
|
||||||
指定处理事件的构件,对于actiontype in ["blocks", "urlwidget"]的事件绑定, target为其父构件,缺省的插入方式为替代,即用事件构造的构件,替换所有target构件中的其他子构件,成为target构件的唯一子构件,可以在事件绑定定义了不等于”replace“的“mode“属性,使得新创建的构件添加在其他构件的后面。
|
|
||||||
|
|
||||||
### mode
|
|
||||||
可选属性,只有在actiontype in ["blocks", "urlwidget"]情况下有效,指定事件创建的构件在target构件中的插入方式,mode==”replace“时,清空target的所有子构件后插入,否则添加到最后。
|
|
||||||
|
|
||||||
### params
|
|
||||||
事件处理指定的静态参数,其值在构件创建时确定,不会改变,实际传递给事件处理的参数为params.update(d), 其中d为datatarget构件的getValue方法返回的结果。如果未定义datatarget,则d={},
|
|
||||||
|
|
||||||
### options
|
|
||||||
可选项,只有在actiontype in ["blocks", "urlwidget"]情况下有效,指定创建构件的构件数据格式options的值需是一个数据字典,且需满足构件数据格式要求。参看[构件数据格式](./cdf.md)
|
|
||||||
|
|
||||||
### conform
|
|
||||||
可选项,如果存在,此事件处理前需要客户点击弹出窗体中的确认键,否则将不会处理
|
|
||||||
conform的数据格式如下:
|
|
||||||
```
|
|
||||||
"conform":{
|
|
||||||
"size_hint":[0.6,0.6],
|
|
||||||
"title":"Conform for delete playlist",
|
|
||||||
"message":"Please conform to delete this play list"
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
其中
|
|
||||||
* size_hint定义弹出窗体占屏幕宽,高的占比
|
|
||||||
|
|
||||||
* title是团出窗体的标题
|
|
||||||
|
|
||||||
* message是显示的内容
|
|
||||||
|
|
||||||
### rfname
|
|
||||||
当actiontype==‘registedfunction’时有效,指定注册函数,在前端应用中需先注册, 使用以下代码注册一个registedfunction
|
|
||||||
```
|
|
||||||
from appPublic.registerfunction import RegisterFunction
|
|
||||||
|
|
||||||
def HelloRF(*args, **kwargs):
|
|
||||||
print('Hello ...')
|
|
||||||
|
|
||||||
rf = RegisterFunciton()
|
|
||||||
rf.register('testrf', HelloRF)
|
|
||||||
```
|
|
||||||
'testrf'即可用于rfname
|
|
||||||
|
|
||||||
### script
|
|
||||||
当actiontype=='script'时有效,其值是一行可执行的python代码
|
|
||||||
|
|
||||||
### dispatch_event
|
|
||||||
当actiontype=='event'时有效,指定需要触发target构件上的事件名称
|
|
||||||
|
|
||||||
|
|
||||||
## 例子
|
|
||||||
|
|
||||||
### urlwidget
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"actiontype":"urlwidget",
|
|
||||||
"wid":"delete",
|
|
||||||
"datawidget":"delete",
|
|
||||||
"target":"root.public_popup",
|
|
||||||
"event":"on_press",
|
|
||||||
"conform":{
|
|
||||||
"size_hint":[0.6,0.6],
|
|
||||||
"title":"Conform for delete playlist",
|
|
||||||
"message":"Please conform to delete this play list"
|
|
||||||
},
|
|
||||||
"options":{
|
|
||||||
"method":"GET",
|
|
||||||
"mode":"replace",
|
|
||||||
"params":{{json.dumps(params_kw)}},
|
|
||||||
"url":"{{entire_url('delete_pldetail_song.dspy')}}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
```
|
|
||||||
命名构件”delete“按钮的”on_press"事件被绑定到了一个“urlwidget”事件处理上,数据来源为“delete”构件, 目标窗体为app.root构件下面的一个”public_popup"的构件。此事件的处理需要用户在弹出窗体中点击确认键后才能处理。
|
|
||||||
|
|
||||||
### method
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"event":"on_press",
|
|
||||||
"actiontype":"method",
|
|
||||||
"wid":"delete",
|
|
||||||
"target":"root.public_popup",
|
|
||||||
"method":"open"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
命名构件“delete”的“on_press"事件调用app.root的public_popup构件的open函数来处理。
|
|
||||||
|
|
||||||
### registedfunction
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"actiontype":"registedfunction",
|
|
||||||
"wid":"playlist_add",
|
|
||||||
"event":"on_submit",
|
|
||||||
"datawidget":"playlist_add",
|
|
||||||
"target":"self",
|
|
||||||
"rfname":"playlist_add"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
"playlist_add"构件的"on_submit"事件绑定在一个registedfunction的处理函数上
|
|
||||||
事件的数据来源与“playlist_add"构件。
|
|
||||||
|
|
||||||
### script
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"actiontype":"script",
|
|
||||||
"wid":"playlist_add",
|
|
||||||
"event":"on_submit",
|
|
||||||
"datawidget":"playlist_add",
|
|
||||||
"target":"self",
|
|
||||||
"script":"print(self, args)"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
"playlist_add"构件的"on_submit"事件绑定了一个script的处理,即打印出target和参数
|
|
||||||
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
# 构件数据格式说明
|
|
||||||
一个构件数据格式必须是一个符合python的字典数据类型,需要至少包含以下属性
|
|
||||||
|
|
||||||
## id
|
|
||||||
定义一个构件的名称,含有此属性的构件为命名构件,命名构件可以通过Blocks.getWidgetById获得。
|
|
||||||
名称规则:名称由字母数字构成,理论上可以包含汉字,绝对不能包含”."(英文句号)
|
|
||||||
|
|
||||||
## widgettype
|
|
||||||
定义构件的名称,大部分常用的kivy的widget的类名都可以用,以及kivyblocks扩展的部件
|
|
||||||
|
|
||||||
## options
|
|
||||||
类构建时的参数,字典数据类型
|
|
||||||
|
|
||||||
## subwidgets
|
|
||||||
子构件数组,数组中的每个元素也必须是一个符合构件数据格式要求的数据字典,用于定义一个子构件。
|
|
||||||
|
|
||||||
## binds
|
|
||||||
构件的事件绑定列表,每个构件(和其命名子构件)的任和事件都可以绑定一道多个处理,详细事件绑定请看[事件绑定](./binds.md)
|
|
||||||
|
|
||||||
## 其他属性
|
|
||||||
非上述属性的其他的字典属性,blocks会试图用此属性值来创建构件,如果成功,则将此构件在当前构件中保存为此属性名称,并可用使用属性名称当变量来调用 Blocks.getWidgetById()函数来获取
|
|
||||||
|
|
||||||
## 例子
|
|
||||||
|
|
||||||
### HELLO
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
##### 说明
|
|
||||||
创建一个VBox类型的构件,VBox创建一个子构件垂直排列的容器,子构件按照顺序从上而下排列,在这个例子中,本VBox容器中放了两个子构件,一个是“title1”的标题1构件,另一个是Text构件,VBox不带参数是表示占满父构件的全部空间。
|
|
||||||
|
|
||||||
##### 显示效果
|
|
||||||
[Hello](../imgs/hello_window.png)
|
|
||||||
|
|
||||||
### 服务器来的构件字典数据
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"widgettype":"urlwidget",
|
|
||||||
"options":{
|
|
||||||
"params":{},
|
|
||||||
"url":"{{entire_url('ctrl.ui')}}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
#### 说明
|
|
||||||
urlwidget的一个特殊的构件类型
|
|
@ -1,9 +0,0 @@
|
|||||||
# kivyblocks中文文档
|
|
||||||
|
|
||||||
## 目录
|
|
||||||
[kivyblocks简介](./intro.md)
|
|
||||||
|
|
||||||
[构件数据格式说明](./cdf.md)
|
|
||||||
|
|
||||||
[常用构件](./components.md)
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
# kivyblocks简介
|
|
||||||
|
|
||||||
kivyblocks是一个基于kivy的python GUI开发工具,得益于kivy的跨平台特性, kivyblocks可以支持Windows,Linux,macosx, iPhone,android, 以及X霉
|
|
||||||
|
|
||||||
|
|
||||||
## kivyblocks的目标
|
|
||||||
降低前端原生应用开发的复杂度,提高原生应用系统的开发和运维效率。
|
|
||||||
|
|
||||||
## kivyblocks的原理
|
|
||||||
逻辑 + 数据 = 程序
|
|
||||||
|
|
||||||
相信程序员都了解上述等式,kviyblocks将复杂的业务逻辑封装在底层的构件库中,而将标准的数据接口提供给程序员,程序员不需要编写逻辑代码
|
|
||||||
|
|
||||||
程序要要创建一个显示构件,只需要按照[构件数据格式](./cdf.md)的要求填写字典数据即可
|
|
||||||
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
# Box
|
|
||||||
Box is a BoxLayout widget with a BGColorBehavior class, when add a Text, or widget contains Text, it will set the Text color as Box's fgcolor.
|
|
||||||
|
|
||||||
It use normal_bgcolor as the background color, and normal_fgcolor as the text color if the Box is not selected, when the Box is selected, it show selected_bgcolor background color, and reset the Text's color inside the Box with selected_fgcolor
|
|
||||||
|
|
||||||
## options
|
|
||||||
|
|
||||||
### color_level
|
|
||||||
default is 0, the main color seials, color level for this widget, please reference to block color for further information
|
|
||||||
### radius: default is [], means not Box corner without radius. if present, it must be a list of 4 float value, indicate radius for the four corners[ top=left, top-right, bottom-right, bottom-left]
|
|
||||||
|
|
||||||
### others options
|
|
||||||
each options accepte by BoxLayout is also accepted by Box
|
|
||||||
|
|
||||||
## Method
|
|
||||||
|
|
||||||
### selected
|
|
||||||
selected draws Box's background with selected_bgcolor, set all the Text widgets's color with selected_fgcolor
|
|
||||||
|
|
||||||
### unselected
|
|
||||||
this method draws Box's background with normal_bgcolor, set all Text widgets's color with normal_fgcolor
|
|
||||||
|
|
||||||
## event
|
|
||||||
no new events
|
|
||||||
|
|
||||||
## refence
|
|
||||||
Horizonal Box[HBox](./hbox.md)
|
|
||||||
Vertical Box[VBox](./vbox.md)
|
|
||||||
Text [Text](./text.md)
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
@ -1,88 +0,0 @@
|
|||||||
|
|
||||||
[CommandBox](commandbox.md)
|
|
||||||
[TinyText](tinytext.md)
|
|
||||||
[SingleCheckBox](singlecheckbox.md)
|
|
||||||
[ClickableBox](clickablebox.md)
|
|
||||||
[ClickableText](clickabletext.md)
|
|
||||||
[ClickableIconText](clickableicontext.md)
|
|
||||||
[ToggleText](toggletext.md)
|
|
||||||
[ToggleIconText](toggleicontext.md)
|
|
||||||
[ClickableImage](clickabkeimage.md)
|
|
||||||
[ToggleImage](toggleimage.md)
|
|
||||||
[LandscopeHide](landscopehide.md)
|
|
||||||
[VideoBehavior](videobehavior.md)
|
|
||||||
[ModalBehavior](modalbehavior.md)
|
|
||||||
[CircleProgress](circleprogress.md)
|
|
||||||
[PyInterpreter](pyinterpreter.md)
|
|
||||||
[UploadFile](uploadfile.md)
|
|
||||||
[FFVideo](ffvideo.md)
|
|
||||||
[AnchorBox](anchorbox.md)
|
|
||||||
[FloatBox](floatbox.md)
|
|
||||||
[RelativeBox](relativebox.md)
|
|
||||||
[GridBox](gridbox.md)
|
|
||||||
[PageBox](pagebox.md)
|
|
||||||
[ScatterBox](scatterbox.md)
|
|
||||||
[StackBox](stackbox.md)
|
|
||||||
[DateInput](dateinput.md)
|
|
||||||
[HTTPSeriesData](httpseriesdata.md)
|
|
||||||
[HTTPDataHandler](httpdatahandler.md)
|
|
||||||
[PageLoader](pageloader.md)
|
|
||||||
[UdpWidget](udpwidget.md)
|
|
||||||
[ScrollPanel](scrollpanel.md)
|
|
||||||
[TextInput](textinput.md)
|
|
||||||
[Markdown](markdown.md)
|
|
||||||
[PagePanel](pagepanel.md)
|
|
||||||
[Conform](conform.md)
|
|
||||||
[Message](message.md)
|
|
||||||
[Error](error.md)
|
|
||||||
[Popup](popup.md)
|
|
||||||
[MapView](mapview.md)
|
|
||||||
[DataGrid](datagrid.md)
|
|
||||||
[FileLoaderBrowser](fileloaderbrowser.md)
|
|
||||||
[QRCodeWidget](qrcodewidget.md)
|
|
||||||
[TabsPanel](tabspanel.md)
|
|
||||||
[TwoSides](twosides.md)
|
|
||||||
[PageContainer](pagecontainer.md)
|
|
||||||
[BoxViewer](boxviewer.md)
|
|
||||||
[Form](form.md)
|
|
||||||
[StrSearchForm](strsearcgform.md)
|
|
||||||
[VPlayer](vplayer.md)
|
|
||||||
[DataGrid](datagrid.md)
|
|
||||||
[Toolbar](toolbar.md)
|
|
||||||
[ToolPage](toolpage.md)
|
|
||||||
[HTTPDataHandler](httpdatahandler.md)
|
|
||||||
[Text](text.md)
|
|
||||||
[ScrollWidget](scrollwidget.md)
|
|
||||||
[BinStateImage](binstateimage.md)
|
|
||||||
[JsonCodeInput](jsoncodeinput.md)
|
|
||||||
[FloatInput](floatinput.md)
|
|
||||||
[IntegerInput](integerinput.md)
|
|
||||||
[StrInput](strinput.md)
|
|
||||||
[SelectInput](selectinput.md)
|
|
||||||
[BoolInput](boolinput.md)
|
|
||||||
[Messager](messager.md)
|
|
||||||
[LoginForm](loginform.md)
|
|
||||||
[PressableImage](pressableimage.md)
|
|
||||||
[PressableLabel](pressablelabel.md)
|
|
||||||
[Tree](tree.md)
|
|
||||||
[TextTree](texttree.md)
|
|
||||||
[MenuTree](menutree.md)
|
|
||||||
[PopupMenu](popupmenu.md)
|
|
||||||
[HostImage](hostimage.md)
|
|
||||||
[APlayer](aplayer.md)
|
|
||||||
[WrapText](wraptext.md)
|
|
||||||
[PressableBox](pressablebox.md)
|
|
||||||
[Title1](title1.md)
|
|
||||||
[Title2](title2.md)
|
|
||||||
[Title3](title3.md)
|
|
||||||
[Title4](title4.md)
|
|
||||||
[Title5](title5.md)
|
|
||||||
[Title6](title6.md)
|
|
||||||
[Modal](modal.md)
|
|
||||||
[TimedModal](timedmodal.md)
|
|
||||||
[HBox](hbox.md)
|
|
||||||
[VBox](vbox.md)
|
|
||||||
[SwipeBox](swipebox.md)
|
|
||||||
[ToggleItems](toggleitems.md)
|
|
||||||
[Accordion](accordion.md)
|
|
||||||
[Slider](slider.md)
|
|
Loading…
Reference in New Issue
Block a user