【发布时间】:2017-01-28 20:05:57
【问题描述】:
我正在学习 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()
【问题讨论】: