Python与根部小部件

0 投票
1 回答
688 浏览
提问于 2025-04-18 10:38

我是一名德国学生,正在学习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

这本书在这里说错了。你可以通过以下方式来修正:

  1. AddLocationForm 的 kv 文件中,添加一个 id: location_form
  2. 调用 location_form.search_location()

另外:

  • 在这个例子中,root 是指 WeatherRoot
  • 在你的测试中,应用里没有 AddLocationForm 这个属性,所以 app.AddLocationForm 是无法使用的。
  • 在你的测试中,你直接尝试使用 AddLocationForm。这只是一个类,而不是一个实例。我们无法知道你想指的是哪个实例。

我猜作者最开始是在 root 下写这个小部件,然后把内容移动到了其他地方,这样就搞乱了 :)

撰写回答