Kivy: Unknown class error code

后端 未结 2 846
迷失自我
迷失自我 2021-02-10 16:17

This is the main.py

from kivy.app import App
    
    
class WeatherApp(App):
    pass
    
    
if __name__ == \'__main__\         


        
2条回答
  •  生来不讨喜
    2021-02-10 16:40

    Kivy ListView » Deprecated

    ListView is no longer defined in the recently released stable Kivy version 1.11.0.

    Kivy RecycleView » MVC (Model-View-Controller)

    The view is generatad by processing the data, essentially a list of dicts, and uses these dicts to generate instances of the viewclass as required. Its design is based on the MVC (Model-view-controller) pattern.

    • Model: The model is formed by data you pass in via a list of dicts.
    • View: The View is split across layout and views and implemented using adapters.
    • Controller: The controller determines the logical interaction and is implemented by RecycleViewBehavior.

    Solution

    To create a RecycleView of selectable item, implement the following classes as part of the viewclass. The item is usually a widget e.g. Label, Button, or a group/row of widgets in a layout (BoxLayout or GridLayout).

    viewclass

    • Selectabel recycle layout class, e.g. SelectableRecycleBoxLayout(), or SelectableRecycleGridLayout()
    • Selectable widget class, e.g. SelectableLabel(), SelectableButton(), or SelectableRow()

    data

    • Creates a list of dicts for data

    Example

    The following example illustrates the equivalence of a ListView by using RecycleView. The viewclass is a selectable RecycleBoxLayout of Label widget. The app is using OpenWeatherMap's API to retrieve a sample weather data of London, GB (Great Britain).

    Note:

    To make calls to OpenWeatherMap using the real API point, you need an API key (APPID).

    main.py

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.recycleview.views import RecycleDataViewBehavior
    from kivy.uix.label import Label
    from kivy.properties import BooleanProperty, ObjectProperty
    from kivy.uix.recycleboxlayout import RecycleBoxLayout
    from kivy.uix.behaviors import FocusBehavior
    from kivy.uix.recycleview.layout import LayoutSelectionBehavior
    from kivy.network.urlrequest import UrlRequest
    from kivy.lang import Builder
    
    import json
    
    
    class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                                     RecycleBoxLayout):
        ''' Adds selection and focus behaviour to the view. '''
    
    
    class SelectableLabel(RecycleDataViewBehavior, Label):
        ''' Add selection support to the Label '''
        index = None
        selected = BooleanProperty(False)
        selectable = BooleanProperty(True)
    
        def refresh_view_attrs(self, rv, index, data):
            ''' Catch and handle the view changes '''
            self.index = index
            return super(SelectableLabel, self).refresh_view_attrs(
                rv, index, data)
    
        def on_touch_down(self, touch):
            ''' Add selection on touch down '''
            if super(SelectableLabel, self).on_touch_down(touch):
                return True
            if self.collide_point(*touch.pos) and self.selectable:
                return self.parent.select_with_touch(self.index, touch)
    
        def apply_selection(self, rv, index, is_selected):
            ''' Respond to the selection of items in the view. '''
            self.selected = is_selected
    
    
    class AddLocationForm(BoxLayout):
        search_input = ObjectProperty()
        search_results = ObjectProperty()
    
        def search_location(self):
            search_template = "https://samples.openweathermap.org/data/2.5/find?q={}&appid=b6907d289e10d714a6e88b30761fae22"
            # search_template = "https://api.openweathermap.org/data/2.5/find?q={}&typle=like&appid=xyz"    # Replace 'xyz' with your API Key (APPID)
            search_url = search_template.format(self.search_input.text)
            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.data = [{'text': str(x)} for x in cities]
            print(f"self.search_results.data={self.search_results.data}")
    
    
    class WeatherRoot(BoxLayout):
        pass
    
    
    class TestApp(App):
        title = "Weather App"
    
        def build(self):
            return Builder.load_file("main.kv")
    
    
    if __name__ == '__main__':
        TestApp().run()
    

    main.kv

    WeatherRoot:
    
    :
        AddLocationForm:
    
    :
        # Draw a background to indicate selection
        canvas.before:
            Color:
                rgba: (1, 0, 0, 1) if self.selected else (.0, 0.9, .1, .3)
            Rectangle:
                pos: self.pos
                size: self.size
            Color:
                rgba: (0, 0.9, .1, .3)
            Rectangle:
                pos: self.pos
                size: self.size
    
    :
        orientation: "vertical"
    
        search_input: search_input
        search_results: search_results_list
    
        BoxLayout:
            height: "40dp"
            size_hint_y:None
    
            TextInput:
                id: search_input
                size_hint_x: 50
                focus: True
                multiline: False
                hint_text: 'Your city name'
                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
    
        RecycleView:
            id: search_results_list
    
            viewclass: 'SelectableLabel'
    
            SelectableRecycleBoxLayout:
                default_size: None, dp(26)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
                multiselect: True
                touch_multiselect: True
    

    Output

提交回复
热议问题