首页 > 解决方案 > 单击按钮时,Kivy 会更新其他类的数据

问题描述

在我的应用程序中,我有一个存储(一个 Json 文件),当我加载我的应用程序时,我有一个从该存储创建的列表。
我在这个应用程序中也有一个按钮,当我点击它时,我想在我的存储中添加一些东西,然后更新我的列表。
问题是列表和按钮是 2 个单独的类,当我尝试list.updateData()on_release() # from the button class我的 .

这是我整个应用程序的代码:
planificateur.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.label import Label
from kivy.properties import BooleanProperty
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.vector import Vector
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.widget import Widget
from kivy.uix.tabbedpanel import TabbedPanel
import random
from kivy.storage.jsonstore import JsonStore
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)

    name=''
    priority=1
    isActive=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
        # if is_selected:
        #     print("selection changed to {0}".format(rv.data[index]))
        # else:
        #     print("selection removed for {0}".format(rv.data[index]))

    def writeInStore(self, name):
        store = JsonStore(name)
        store.put(self.name, priority=self.priority, isActive=self.isActive, task="task")


class RV(RecycleView):

    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.updateData()

    def my_callback(self,dt):
        self.updateData()

    def updateData(self): #I would like to use this method, on the current instance of self when I click on the button. 
        store = JsonStore('test.json')
        self.data = [{'text' : str(task[0]) + " " + str(task[1].get('priority'))} for task in store.find(task="task") ]
        self.refresh_from_data() 

    def addTask(self, task):
        self.taskList.append(task)
        self.updateData()

    def getOneRandom(self):
        pass

class AddTaskButton(ButtonBehavior, Widget):
    def __init__(self, **kwargs):
        super(AddTaskButton, self).__init__(**kwargs)

    def collide_point(self, x, y):
        return Vector(x, y).distance(self.center) <= self.width / 2

    def on_release(self):
        task= SelectableLabel();
        task.name ="test22"
        task.priority = 1
        task.isActive = False
        task.writeInStore('test.json')
        rv = RV() #Here I have to call for another instance of RV, so modification are not made inside the running app
        rv.updateData() 
class Main(TabbedPanel):
     pass

class PlanificateurApp(App):
    def build(self):
        return Main()

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

planificateur.kv

<AddTaskButton>:
    size: (min(self.width,self.height),min(self.width,self.height)) # force circle
    canvas.before:
        Color:
            rgb: 0.75, 0.75, 0.75
        Ellipse:
            pos: self.pos
            size: self.size


<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
<RV>:
    viewclass: 'SelectableLabel'
    SelectableRecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        multiselect: False
        touch_multiselect: True

<Main>:
    do_default_tab: False

    TabbedPanelItem:
        text: 'first tab'
        Label:
            text: "app.todayTask"
    TabbedPanelItem:
        text: 'tab2'
        FloatLayout:
            RV:
                id:rv
            AddTaskButton:
                id:tb
                size_hint: .1, .1
                pos_hint:{'right': 1}

SelectableRecycleBoxLayout并且SelectableLabel来自关于 Selecatble 项目列表的 Kivy 教程。
我已经把评论RV.updateData()AddTaskButton.on_release()解释。

我必须从我的 RV 类创建一个单例吗?(我不确定在 python 中是否可行?)或者我有办法检索当前运行的 RV 实例以便调用我的函数吗?还是我的逻辑错了?我试图在Main类中创建一个函数,从 kv 文件中的 id 检索类的实例,但它没有做任何事情。
有人可以帮助我吗?

标签: pythonkivykivy-language

解决方案


推荐阅读