Kivy:使用RecycleView删除JSON中的数据

时间:2018-11-13 01:44:43

标签: python json kivy

我想使用store.delete('key_of_dictionary')从JSON文件中删除数据,方法是在RecycleView中选择一个标签,然后按“删除”按钮。

我已经编写了代码来选择标签并获取值,但是我无法将其传递给方法/函数。看起来,该方法必须位于class SelectableLabel(...)中。我不确定如何访问该类。

我将不胜感激。 提前谢谢!

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.properties import BooleanProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.storage.jsonstore import JsonStore
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from operator import itemgetter
import json

kv_string = """
ScreenManager:
    id: manager

    Screen:
        BoxLayout:
            orientation: 'vertical'
            canvas:
                Color:
                    rgba: .2,.2,.5,1
                Rectangle:
                    pos: self.pos
                    size: self.size

            GridLayout:
                size_hint_y: .3
                cols:4
                MyButton:
                    text: 'Rank'
                    size_hint_x: 0.5
                MyButton:
                    text: 'Ratings'
                MyButton:
                    text: 'Name'
                    size_hint_x: 2
                MyButton:
                    text: 'Score'
                    on_press:
                        #arrange the boxing in ascending or descending order

            RecycleView:
                data: [{'text': str(x)} for x in app.new_new_sorted_data]
                viewclass: 'SelectableLabel'

                SelectableRecycleGridLayout:
                    cols: 4
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
                    multiselect: True
                    touch_multiselect: True

            Button:
                size_hint_y: .3
                text: 'Press to Use Method'
                on_press:
                    SelectableLabel().function()

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size

<MyButton@Button>:
    background_color: 0,0,0,1
"""
class SelectableLabel(RecycleDataViewBehavior, Label):

    def function(self):
        print('Take the value in rv.data[index] if 4 % == 0 then do\nstore.delete(rv.data[index])')

    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_layout(self, rv, index, layout, viewport):
        mod = index % 4
        size_hints = [(0.5, None), (1, None), (2, None), (1, None)]
        layout['size_hint'] = size_hints[mod]
        colors = (1,1,1,1), (1,1,1,1), (1,1,1,1), (0,1,1,1)
        layout['color'] = colors[mod]
        super(SelectableLabel, self).refresh_view_layout(rv, index, layout, viewport)

    def refresh_view_attrs(self, rv, index, data):
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        if super(SelectableLabel, self).on_touch_down(touch):
            return True

        if self.collide_point(*touch.pos) and self.selectable:
            self.parent.select_with_touch(self.index, touch)
            if self.index % 4 == 0:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index + 2)
                self.parent.select_with_touch(self.index + 3)
                return
            elif self.index % 4 == 1:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index + 2)
                self.parent.select_with_touch(self.index - 1)
                return
            elif self.index % 4 == 2:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index - 2)
                self.parent.select_with_touch(self.index - 1)
                return
            elif self.index % 4 == 3:
                self.parent.select_with_touch(self.index - 1)
                self.parent.select_with_touch(self.index - 2)
                self.parent.select_with_touch(self.index - 3)
                return

    index_list = []

    def apply_selection(self, rv, index, is_selected):
        self.selected = is_selected

        if is_selected:
            self.index_list.append(rv.data[index]) if index % 4 == 0 else self.index_list
            print(self.index_list)  if index % 4 == 0 else ''
            #print("selection changed to {0}".format(rv.data[index]))
        else:
            try:
                self.index_list.remove(rv.data[index]) if index % 4 == 0 else self.index_list
                print(self.index_list) if index % 4 == 0 else ''
                #print("selection removed for {0}".format(rv.data[index]))
            except:
                pass

class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior, RecycleGridLayout):
    pass

class MyApp(App):

    store = JsonStore('file.json')
    store.put('Example: 1', value_1 = 'Rating: C', value_2 = 10, value_3 = 'Zack')
    store.put('Example: 2', value_1 = 'Rating: C', value_2 = 13, value_3 = 'Kate')
    store.put('Example: 3', value_1 = 'Rating: A', value_2 = 32, value_3 = 'Pete')
    store.put('Example: 4', value_1 = 'Rating: B', value_2 = 24, value_3 = 'Toby')
    store.put('Example: 5', value_1 = 'Rating: D', value_2 = 03, value_3 = 'Lars')

# ---------------------- v Sorting Data v ----------------------

    json_data = open('./file.json')
    score_data = json.load(json_data)

    newlist = []
    newnewlist = []

    for x in score_data:
        newlist.append(x)

    for y in newlist:
        newnewlist.append(score_data[str(y)])

    print(newlist)
    print(newnewlist)

    sorted_data = sorted(newnewlist,key=itemgetter('value_2'), reverse = True)
    new_sorted_data = []

    for z in sorted_data:
        new_sorted_data.append(z.values())

    new_new_sorted_data = []

    for x,y,z in new_sorted_data:

        new_new_sorted_data.append(newlist.pop())
        new_new_sorted_data.append(x)
        new_new_sorted_data.append(y)
        new_new_sorted_data.append(z)

# ---------------------- ^ Sorting Data ^ ----------------------

    def build(self):
        root_widget = Builder.load_string(kv_string)
        return root_widget

if __name__ == "__main__":
    MyApp().run()

1 个答案:

答案 0 :(得分:0)

我终于有了示例代码来完成我想要的事情。我完成了MyApp类的学习,进入了SelectLabel类。我还找到了一种通过RecycleView删除特定JSON密钥的方法。我没有评论这段代码,因为它只是一个示例,但是如果有人将其用作参考并需要帮助,请随时给我发消息。

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.properties import BooleanProperty, ListProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.storage.jsonstore import JsonStore
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from operator import itemgetter
import json

kv_string = """
ScreenManager:
    id: manager

    Screen:
        BoxLayout:
            orientation: 'vertical'
            canvas:
                Color:
                    rgba: .2,.2,.5,1
                Rectangle:
                    pos: self.pos
                    size: self.size

            GridLayout:
                size_hint_y: .3
                cols:4
                MyButton:
                    text: 'Rank'
                    size_hint_x: 0.5
                MyButton:
                    text: 'Ratings'
                MyButton:
                    text: 'Name'
                    size_hint_x: 2
                MyButton:
                    text: 'Score'
                    on_press:
                        #arrange the boxing in ascending or descending order

            RecycleView:
                data: [{'text': str(x)} for x in app.new_new_sorted_data]
                viewclass: 'SelectableLabel'

                SelectableRecycleGridLayout:
                    cols: 4
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
                    multiselect: True
                    touch_multiselect: True

            Button:
                size_hint_y: .3
                text: 'Press to Use Method'
                on_press:
                    app.pre_function()

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size

<MyButton@Button>:
    background_color: 0,0,0,1
"""
class SelectableLabel(RecycleDataViewBehavior, Label):

    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_layout(self, rv, index, layout, viewport):
        mod = index % 4
        size_hints = [(0.5, None), (1, None), (2, None), (1, None)]
        layout['size_hint'] = size_hints[mod]
        colors = (1,1,1,1), (1,1,1,1), (1,1,1,1), (0,1,1,1)
        layout['color'] = colors[mod]
        super(SelectableLabel, self).refresh_view_layout(rv, index, layout, viewport)

    def refresh_view_attrs(self, rv, index, data):
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        if super(SelectableLabel, self).on_touch_down(touch):
            return True

        if self.collide_point(*touch.pos) and self.selectable:
            self.parent.select_with_touch(self.index, touch)
            if self.index % 4 == 0:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index + 2)
                self.parent.select_with_touch(self.index + 3)
                return
            elif self.index % 4 == 1:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index + 2)
                self.parent.select_with_touch(self.index -1)
                return
            elif self.index % 4 == 2:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index - 2)
                self.parent.select_with_touch(self.index -1)
                return
            elif self.index % 4 == 3:
                self.parent.select_with_touch(self.index - 1)
                self.parent.select_with_touch(self.index - 2)
                self.parent.select_with_touch(self.index - 3)
                return

    index_list = []

    def apply_selection(self, rv, index, is_selected):
        self.selected = is_selected

        if is_selected:
            self.index_list.append(rv.data[index]) if index % 4 == 0 else self.index_list
            #print("selection changed to {0}".format(rv.data[index]))
        else:
            try:
                self.index_list.remove(rv.data[index]) if index % 4 == 0 else self.index_list
                #print("selection removed for {0}".format(rv.data[index]))
            except:
                pass

class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior, RecycleGridLayout):
    pass

class MyApp(App):
    store = JsonStore('file.json')
    store.put('Example: 1', value_1 = 'Rating: C', value_2 = 10, value_3 = 'Zack')
    store.put('Example: 2', value_1 = 'Rating: C', value_2 = 13, value_3 = 'Kate')
    store.put('Example: 3', value_1 = 'Rating: A', value_2 = 32, value_3 = 'Pete')
    store.put('Example: 4', value_1 = 'Rating: B', value_2 = 24, value_3 = 'Toby')
    store.put('Example: 5', value_1 = 'Rating: D', value_2 = 03, value_3 = 'Lars')

# ---------------------- v Sorting Data v ----------------------

    new_new_sorted_data = ListProperty([])

    def sort_data(self):
        try:
            self.store = JsonStore('file.json')
            self.new_new_sorted_data = []
            json_data = open('./file.json')
            score_data = json.load(json_data)

            newlist = []
            newnewlist = []

            for x in score_data:
                newlist.append(x)

            for y in newlist:
                newnewlist.append(score_data[str(y)])

            print(newlist)
            print(newnewlist)

            sorted_data = sorted(newnewlist,key=itemgetter('value_2'), reverse = True)
            new_sorted_data = []

            for z in sorted_data:
                new_sorted_data.append(z.values())


            for x,y,z in new_sorted_data:

                self.new_new_sorted_data.append(newlist.pop())
                self.new_new_sorted_data.append(x)
                self.new_new_sorted_data.append(y)
                self.new_new_sorted_data.append(z)
        except:
            pass
# ---------------------- ^ Sorting Data ^ ----------------------

# --------------------- v Deleting Data v ----------------------

    only_key_values_list = []
    only_key_values = []

    def pre_function(self):
        self.only_key_values_list = []
        self.only_key_values = []

        for value in SelectableLabel().index_list:
            self.only_key_values_list.append(value.values())
            for keys in self.only_key_values_list:
                for key in keys:
                    try:
                        self.store.delete(str(key))
                    except:
                        pass
            self.sort_data()


# --------------------- ^ Deleting Data ^ ----------------------
    def __init__(self, **kwargs):
        super(MyApp, self).__init__(**kwargs)
        self.sort_data()

    def build(self):
        root_widget = Builder.load_string(kv_string)
        return root_widget

if __name__ == "__main__":
    MyApp().run()