从kivy适配器小部件中删除ListItemButtons

时间:2014-10-04 23:19:55

标签: android python listview kivy

好的,我正在使用基于搜索城市的listitembuttons填充列表。它将使用listitembutton为列表填充匹配输入文本的每个城市。当我进入一个新的城市时,我想删除其他listitembuttons并将其替换为我搜索过的新城市列表。我可以使用这段代码删除它们。

def clear_locations(self):
        for x in self.search_results.adapter.data:
            self.search_results.adapter.data.remove(x)

如果我使用此函数打印x i n self.search_results.adapter.data:例如,当我搜索伦敦时:它将在其自己的ListItemButton中打印出四个城市。但是,它仅删除ListItemButtons的数量等于创建的新数量。

假设我首先搜索伦敦并获得四个listitembuttons。然后我搜索巴黎。它删除了两个伦敦listitembuttons并添加了两个paris。如果我搜索murfreesboro,它将删除伦敦listitembuttons之一,并添加一个murfreesboro之一。我不能得到的是,四个循环将通过并打印数据中的所有城市,但只会删除等于新城市数量的金额。任何帮助都会很棒。

这是我的其余代码: main.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty, ListProperty, StringProperty, NumericProperty
from kivy.network.urlrequest import UrlRequest
import json
from kivy.adapters.listadapter import ListAdapter
from kivy.uix.listview import ListItemButton

class WeatherRoot(BoxLayout):

    location_form = ObjectProperty()
    current_weather = ObjectProperty()

    def show_current_weather(self, location=None):
        self.clear_widgets()

        if location is not None:
            self.current_weather = CurrentWeather(location=location)

        if self.current_weather is None:
            self.current_weather = CurrentWeather()

        if location is None:
            self.current_weather.location = location

        self.current_weather.update_weather()    
        self.add_widget(self.current_weather)

    def add_location(self):
        self.clear_widgets()
        self.add_widget(self.location_form)

class CurrentWeather(BoxLayout):
    location = ListProperty(["NewYork", "US"])
    conditions = StringProperty()
    temp = NumericProperty()
    temp_min = NumericProperty()
    temp_max = NumericProperty()
    wind = NumericProperty()
    humidity = NumericProperty()

    def update_weather(self):
        weather_template = "http://api.openweathermap.org/data/2.5/weather?q={},{}&units=imperial&APID=a1bf58ef2e81e600af117e12e13e0ff1"
        weather_url = weather_template.format(*self.location)
        request = UrlRequest(weather_url, self.weather_retrieved)

    def weather_retrieved(self, request, data):
        self.conditions = data['weather'][0]['description']
        self.temp = data['main']['temp']
        self.temp_min = data['main']['temp_min']
        self.temp_max = data['main']['temp_max']
        self.wind = data['wind']['speed']
        self.humidity = data['main']['humidity']

class LocationButton(ListItemButton):
    location = ListProperty()

class AddLocationForm(BoxLayout):

    search_input = ObjectProperty() 
    search_results = ObjectProperty()

    def args_converter(self, index, data_item):
        (city, country) = data_item
        return {'location':(city,country)} 

    def web_error(self, *args, **kwargs):
        self.search_results.data = ["Either the openweather.org is down", "or you are not connected to the interweb"]

    def clear_locations(self):
        for x in self.search_results.adapter.data:
            self.search_results.adapter.data.remove(x)


    def search_location(self):
        self.clear_locations()      
        search_template = "http://api.openweathermap.org/data/2.5/find?q={}&type=like&APID=a1bf58ef2e81e600af117e12e13e0ff1"
        search_url = search_template.format(self.search_input.text)
        request = UrlRequest(search_url, self.found_location, on_error=self.web_error)


    def found_location(self, request, data):
        try:
            cities = [(d['name'], d['sys']['country']) for d in data['list']]
        except:
            cities = ["No",  "Citys Found"]
        self.search_results.adapter.data[:]
        self.search_results.adapter.data.extend(cities)
        self.search_results._trigger_reset_populate()



class WeatherApp(App):
    pass

if __name__ == '__main__':
    WeatherApp().run()

weather.kv

#: import main main
#: import ListAdapter kivy.adapters.listadapter.ListAdapter

WeatherRoot:


<WeatherRoot>:
    location_form: add_location_form
    AddLocationForm:
        id: add_location_form

<LocationButton>:
    text: "{}({})".format(self.location[0], self.location[1])
    size_hint_y: None
    height: "40dp"
    color: [1, 1, 1, 1]
    deselected_color: 0,.8,.5,1
    on_press: app.root.show_current_weather(self.location)

<CurrentWeather>:
    orientation: 'vertical'
    Label:
        text: "{}({})".format(root.location[0], root.location[1])
    Label:
        text: root.conditions
    Label:
        text: "Current Temp: {}".format(root.temp)
    Label:
        text: "Low: {}".format(root.temp_min)
    Label:
        text: "High: {}".format(root.temp_max)
    Label:
        text: "Wind Speed: {}".format(root.wind)
    Label:
        text: "Humiditity: {}".format(root.humidity)
    BoxLayout:
        orientation: 'horizontal'
        size_hint_y: None
        height: "40dp"
        Button:
            text: "Add Location"
            on_press: app.root.add_location()
        Button:
            text: "Forcast"

<AddLocationForm>:
    orientation: 'vertical'
    search_input: search_box
    search_results: search_results_list
    BoxLayout:
        size_hint_y: None
        height: "40dp"
        TextInput:
            id: search_box
            focus: True
            multiline: False
            size_hint_x: 50
            on_text_validate: root.search_location()
        Button:
            text: 'Search'
            size_hint_x: 25
            on_press: root.search_location()
        Button:
            text: 'Current Location'
            size_hint_x: 25

    ListView:
        id: search_results_list
        adapter:
            ListAdapter(data = [], cls = main.LocationButton, args_converter = root.args_converter)

因此,如果我在搜索伦敦后搜索paris时使用for循环在self.search_results.adapter.data中打印x,我会在控制台中看到:

(u'London', u'CA')
(u'London', u'GB')
(u'London Borough of Harrow', u'GB')
(u'Londonderry County Borough', u'GB')

但是如果我在self.search_results.adapter.data中使用remove(x)for x:那么我在搜索伦敦后搜索paris时会得到这个: enter image description here

1 个答案:

答案 0 :(得分:0)

UPDATE!找到了一个很好的解决方案!

如果其他人有这个问题我用

解决了
def clear_locations(self):
    del self.search_results.adapter.data[:]