Python与根部小部件
我是一名德国学生,正在学习Kivy这个框架。我买了O'Reilly出版的《Creating Apps in Kivy》这本书来入门这个主题。 书里的作者说我应该创建一个根部小部件(Root Widget),并且这个根部小部件下面要有一个叫“AddLocationForm”的子小部件。 这是KV代码:
#: import ListItemButton kivy.uix.listview.ListItemButton
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
WeatherRoot:
<WeatherRoot>:
AddLocationForm:
orientation: "vertical"
search_input: search_box
search_results: search_result_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: "Current Location"
size_hint_x: 25
ListView:
id: search_result_list
adapter:
ListAdapter(data=[], cls=ListItemButton)
这是Python代码:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.network.urlrequest import UrlRequest
class WeatherRoot(BoxLayout):
pass
class AddLocationForm(BoxLayout):
search_input = ObjectProperty()
search_results = ObjectProperty()
def search_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)
def found_location(self, request, data):
cities = ["{}({})".format(d['name'], d['sys']['country'])
for d in data['list']]
if not cities:
self.search_results.item_strings = ["Nothing found"]
else:
self.search_results.item_strings = cities
class WeatherApp(App):
pass
if __name__ == '__main__':
WeatherApp().run()
现在如果我按下“搜索”按钮,当然会出现以下错误信息:
文件 ".\weatherapp.kv",第18行, on_press: root.search_location() 属性错误:'WeatherRoot'对象没有'search_location'这个属性
这个错误的意思是,它应该在AddLocationForm里找“search_location”这个函数,而不是在根部类里。 我尝试了以下几种方法:
- on_press: app.AddLocationForm.search_location()
- on_press: AddLocationForm.search_location()
但是都没有成功。根据作者的说法,应该是叫“root.search_location()”。
有没有人知道该怎么解决这个问题呢?
1 个回答
1
这本书在这里说错了。你可以通过以下方式来修正:
- 在
AddLocationForm
的 kv 文件中,添加一个id: location_form
。 - 调用
location_form.search_location()
。
另外:
- 在这个例子中,
root
是指WeatherRoot
。 - 在你的测试中,应用里没有
AddLocationForm
这个属性,所以app.AddLocationForm
是无法使用的。 - 在你的测试中,你直接尝试使用
AddLocationForm
。这只是一个类,而不是一个实例。我们无法知道你想指的是哪个实例。
我猜作者最开始是在 root
下写这个小部件,然后把内容移动到了其他地方,这样就搞乱了 :)