我正在学习Kivy,并且这段代码的目的是缓存一个小部件,但我无法理解它的内容:
class WeatherRoot(BoxLayout):
current_weather = ObjectProperty()
def show_current_weather(self, location=None):
self.clear_widgets()
print(WeatherRoot.current_weather)
print(self.current_weather)
if location is None and self.current_weather is None:
location = 'New York (US)'
if location is not None:
self.current_weather = Factory.CurrentWeather()
self.current_weather.location = location
self.add_widget(self.current_weather)
问题是current_weather
,据我所知这是一个类变量,被定义为ObjectProperty
,因为我没有实例变量(我认为是这样)覆盖此变量,当我引用self.current_weather
时我指的是类变量,所以我认为self.current_weather
与WeatherRoot.current_weather
相同,但是当我打印这些变量时我不是期望两者都是ObjectProperty
个实例,我得到了:
<ObjectProperty name=current_weather>
None
我的观点是,此变量永远不会是None
,因为它是一个类变量,所以它始终是ObjectProperty
,但似乎可能是None
,我不明白为什么。
这是此应用程序的GUI:
这是我的Kivy档案:
WeatherRoot:
<WeatherRoot>:
AddLocationForm
<LocationButton>:
on_press: app.root.show_current_weather(self.text)
<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
focus: True
multiline: False
on_text_validate: root.search_location()
Button:
text: 'Search'
size_hint_x: 25
on_press: root.search_location()
Button:
text: 'Current Search'
size_hint_x: 25
ListView:
id: search_results_list
adapter:
ListAdapter(data=[], cls=main.LocationButton)
Button:
height: '40dp'
size_hint_y: None
text: 'Cancel'
on_press: app.root.show_current_weather(None)
因此,当我按下取消按钮并且之前没有搜索过任何位置时,默认值是硬编码的,因为可以看到'New York (US)
。当我先前搜索过某个位置并按下取消按钮时,会显示此位置。
有人可以解释一下这个变量current_weather
是怎么回事吗?我认为不需要这个类变量,但是当我删除它时,我的应用程序崩溃了。
如果您需要,这是我的全部代码:
import json
from kivy.app import App
from kivy.network.urlrequest import UrlRequest
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListItemButton
from kivy.factory import Factory
class WeatherRoot(BoxLayout):
current_weather = ObjectProperty()
def show_current_weather(self, location=None):
self.clear_widgets()
print(WeatherRoot.current_weather)
print(self.current_weather)
if location is None and self.current_weather is None:
location = 'New York (US)'
if location is not None:
self.current_weather = Factory.CurrentWeather()
self.current_weather.location = location
self.add_widget(self.current_weather)
def show_add_location_form(self):
self.clear_widgets()
self.add_widget(AddLocationForm())
class LocationButton(ListItemButton):
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&APPID=' \
'090428d02304be901047796d430986e3'
search_url = search_template.format(self.search_input.text)
print(search_url)
request = UrlRequest(search_url, self.found_location)
def found_location(self, request, data):
data = json.loads(data.decode()) if not isinstance(data, dict) else data
cities = ['{} ({})'.format(d['name'], d['sys']['country'])
for d in data['list']]
# self.search_results.item_strings = cities
self.search_results.adapter.data.clear()
self.search_results.adapter.data.extend(cities)
self.search_results._trigger_reset_populate()
class WeatherApp(App):
pass
WeatherApp().run()