您的位置:首页 > 其它

kivy chapter1~chapter3

2015-05-29 17:21 218 查看

Kivy

rootwidget&childwidgets

WeatherRoot:

<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)设置貌似没有。

WeatherRoot: <WeatherRoot>: AddLocationForm

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐
章节导航