kivy chapter1~chapter3
2015-05-29 17:21
218 查看
Kivy
rootwidget&childwidgetsWeatherRoot: <WeatherRoot>: AddLocationForm <AddLocationForm>: orientation:"vertical" search_input:search_box search_results:search_results_list BoxLayout: height:"40dp" size_hint_y:None TextInput: id:search_box size_hint_x:50 Button: text:"Search" size_hint_x:25 on_press:root.search_location() Button: text:"CurrentLocation" size_hint_x:25 ListView: id:search_results_list adapter: ListAdapter(data=[],cls=main.LocationButton)
<LocationButton>:
on_press:app.root.show_current_weather(self.text)
rootwidget形如WeatherRoot
childwidgets形如AddLocationForm,LocationButton
其中比较重要的区别定义当中root和app.root的使用,这分别引用(refersto)不懂的对象(object)在KVlanguagefile.
app.root始终关联rootwidget,root则关联‘当前’的widget
Becarefulnottoconfusetherootmagicvariable,whichreferstotheleftmostruleinthecurrentindentationblock,withapp.root,whichalwaysreferstotherootwidgetoftheapp.app.rootreferstothesameobjectanywhereintheKVlanguagefile,butrootreferstoadifferentthingdependingonwhatruleitisfoundin.
3.值得注意的是AddLocationForm中ListViewAdapter中的main,这里的main指的是类似‘模块’,main.LocationButton则是传递一个‘类模板'给adpter用于初始化ListView的对象。以下贴出Pythoncode的代码(即main.py):
对应rootwidget的class:
classWeatherRoot(BoxLayout):
defshow_current_weather(self,location):
fromkivy.uix.labelimportLabel
self.clear_widgets()
#self.add_widget(Label(text=location))
current_weather=Factory.CurrentWeather()
current_weather.location=location
self.add_widget(current_weather)
defshow_add_location_form(self):
self.clear_widgets()
self.add_widget(AddLocationForm())
对应childwidget的class:
classAddLocationForm(BoxLayout):
search_input=ObjectProperty()
search_results=ObjectProperty()
defsearch_location(self):
search_template="http://api.openweathermap.org/data/2.5/find?q={}&type=like"
search_url=search_template.format(self.search_input.text)
request=UrlRequest(search_url,self.found_location)
deffound_location(self,request,data):
data=json.loads(data.decode())ifnotisinstance(data,dict)elsedata
cities=["{}({})".format(d['name'],d['sys']['country'])fordindata['list']]
self.search_results.item_strings=cities
delself.search_results.adapter.data[:]
self.search_results.adapter.data.extend(cities) self.search_results._trigger_reset_populate()
以及用于生成按钮风格的ListView的class:
classLocationButton(ListItemButton):
pass
LocationButton只是单纯地继承ListItemButton.其中LiteItemButton源自:
fromkivy.uix.listviewimportListItemButton
值得注意的的是rootwidgetWeatherRoot的“属性”(property)设置貌似没有。
properties
通常在网页里面,比如一个文本输入框里面的值是怎么获取的,这就不得不了解property.
还是以childwidgetAddLocationForm为栗子:
<AddLocationForm>:
orientation:"vertical"
search_input:search_box
search_results:search_results_list
BoxLayout:
height:"40dp"
size_hint_y:None
TextInput:
id:search_box
size_hint_x:50
Button:
text:"Search"
size_hint_x:25
on_press:root.search_location()
Button:
text:"CurrentLocation"
size_hint_x:25
ListView:
id:search_results_list
adapter:
ListAdapter(data=[],cls=main.LocationButton)
oritation,search_input,height,id,size_hint_x等都是property.
其中oritation不同于search_input和search_results,search_input和search_results是Pythoncode代码里面的逻辑产生的,KVlanguagefile里面引用,只在界面与布局里面简单使用。
以下是AddLocationForm的对应的Pythoncode,为了阅读简洁,我略去了一个method:
classAddLocationForm(BoxLayout):
search_input=ObjectProperty()
search_results=ObjectProperty()
defsearch_location(self):
search_template="http://api.openweathermap.org/data/2.5/find?q={}&type=like"
search_url=search_template.format(self.search_input.text)
request=UrlRequest(search_url,self.found_location)
对于不同的widget,形如文本输入框或者按钮,对应的属性不同。特别地,还有独有的eventproperty.
Widget
<CurrentWeather@BoxLayout>:
location:""
orientation:"vertical"
Label:
text:root.location
BoxLayout:
orientation:"horizontal"
height:"40dp"
size_hint_y:None
Button:
text:"AddLocation"
on_press:app.root.show_add_location_form()
Button:
text:"ForeCast"
CurrentWeathor是一个Layoutclasses.按《creatingappinkivy》作者的说法,Widget有如下分类:
Widgets
Kivyusesthewordwidgettodescribeanyuserinterfaceelement.Justafewexamplesofwidgetsinclude:
•ThelabelyourenderedinExample1-3
•Thetextinputfieldandbuttonsyou’llrendershortly
•Layoutclassesthatcompriseotherwidgetsanddeterminewheretheyshouldbedisplayed
•Complicatedtreeviewssuchasfilepickers
•Movieandphotorenderers
•Tabbedboxesthatdisplaydifferentwidgetsdependingontheselectedtab
Ifinditconvenienttothinkofawidgetasasortofboxthathasbehaviorsandcancontainotherboxes.TheWidgetclassisthemostbasicsuchbox.
event
借助上面的代码,首先聚焦Button,text表名这个button的名称,on_press的值指明了当这个按钮被按下的事件由rootwidget对应的class的方法来具体响应。再来看看PythonCode代码,看看事件具体是如何响应的:
classWeatherRoot(BoxLayout):
defshow_current_weather(self,location):
fromkivy.uix.labelimportLabel
self.clear_widgets()
#self.add_widget(Label(text=location))
current_weather=Factory.CurrentWeather()
current_weather.location=location
self.add_widget(current_weather)
defshow_add_location_form(self):
self.clear_widgets()
self.add_widget(AddLocationForm())
1.首先调用clear_widgets方法清除所有widgets(按函数的名称字面上来理解至少是这样的)
2.然后rootwidget调用add_widget方法来创建一个新的AddLocationForm'页面'(views)
最后形如clear_widget和add_widget方法如同extend、_trigger_reset_populate方法一样,似飞来之物。所以要多看手册文档,甚至作者说的,_trigger_reset_populate方法是一个undocumentedmethod,需要看源代码才能获悉这样的函数(data变化来forceanupdatehere),这毋庸置疑需要看ListViews.
self.search_results.adapter.data.extend(cities) self.search_results._trigger_reset_populate()
2015/05/29
相关文章推荐
- hadoop源码剖析--hdfs安全模式
- scanf() scanf_s() 区别
- JAVA作业—从命令行输入两个参数打开文件并计算代码行数 .
- .NET 4.0下使用 SignalR (2)
- JavaScript UserAgent判断---摘自Professional JavaScript for Web Developers 3rd
- ASM(active shape model)算法简介(一)
- Java编程思想之-匿名内部类
- OpenDaylight学习 ( by quqi99 )
- Node.js 函数
- Node.js 路由
- 自动填充英文字母序列
- 第一次提交代码到github时经常遇到的问题
- 【leetcode】Sqrt(x)
- Solr查询query效果对比
- Tomcat 7最大并发连接数的正确修改方法
- JavaSE之面向对象
- 如何使用NetScaler实现http页面跳转https
- 第一次作业:源代码计算器 学习流程
- Node.js模块系统
- Node.js 事件