user2602876
user2602876

Reputation: 15

Python and Root Widgets

I'm a German student and trying to learn Kivy. I have bought the O'Reilly book "Creating Apps in Kivy" to get into this topic. The author say that I should create a Root Widget with a child Widget named "AddLocationForm". The KV Code:

#: 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)       

The Python Code:

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()

If I now press the Button "Search" of course the following Traceback appears:

File ".\weatherapp.kv", line 18, in on_press: root.search_location() AttributeError: 'WeatherRoot' object has no attribute 'search_location'

He must search the "search_location" function in the AddLocationForm and not in the root class. I have tried the following steps:

none of them worked. According to the author it must called "root.search_location()".

Have anyone out there a idea?

Upvotes: 0

Views: 696

Answers (1)

tito
tito

Reputation: 13251

The book is wrong here. You can fix it by:

  1. Add an id: location_form under the AddLocationForm in the kv
  2. Call location_form.search_location().

Also:

  • In this example, root refers to WeatherRoot.
  • In your test, there is no AddLocationForm attribute in your app, so app.AddLocationForm won't work.
  • In your test, you tried to use directly AddLocationForm. This is just a class, not the instance. We can't know which instance you wanted to refer too.

I guess the author first write the widget under , and move the content to , which break things :)

Upvotes: 1

Related Questions