从 Kivy 绑定更新自定义 属性?

Update custom property from Kivy binding?

我希望能够在我将值传递给 Kivy 时更新自定义小部件 class 属性。我不确定这是否与绑定相同。我已阅读有关 Event Dispatcher 的内容,但我无法使其正常工作。

例如,给出下面的代码,我想在 Kivy 中传递 chart_type: 'barh',每当我 运行 程序时,它应该显示一个水平条。

但是,我的大脑似乎不明白该怎么做。有人能指出我正确的方向吗?

from kivy.event import EventDispatcher
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
from kivy.properties import (
    ListProperty,
    StringProperty,
)

kv = """
BoxLayout:
    MDBarChart:
        id: bar
        chart_type: 'barh' # Not working
    MDFlatButton:
        text: "Update"
        # on_press: app.mdchart.update()
"""


class MDBarChart(FigureCanvasKivyAgg, EventDispatcher):

    x_nums = ListProperty([1, 2, 3])
    y_nums = ListProperty([2, 5, 7])
    label_x = StringProperty('x')
    label_y = StringProperty('y')

    # Be able to change this in kivy lang and reflect on Kivy
    chart_type = StringProperty('bar')


    def on_chart_type(self, instance, value):
        self.chart_type = self.chart_type


    def update(self):
        blue_dot = mlines.Line2D(range(1), range(1), marker='o', color='#6200EA',
                                 markersize=15, label='Purple Dot', linewidth=0)

        x = self.x_nums
        y = self.y_nums

        if self.chart_type == "bar":
            plt.bar(x, y, label='Bars1', color='#6200EA')
        elif self.chart_type == "barh":
            plt.barh(x, y, label='Bars1', color='#6200EA')
        elif self.chart_type == "line":
            plt.plot(x, y, label='Bars1', color='#6200EA')
        elif self.chart_type == "stackplot":
            plt.stackplot(x, y, color=['#6200EA','#D1C4E9', '#5E35B1'])

        plt.xlabel(self.label_x)
        plt.ylabel(self.label_y)
        plt.legend(handles=[blue_dot], loc='upper right', prop={'size': 14})

    def remove_borders(self):
        for spine in plt.gca().spines.values():
            spine.set_visible(False)

        plt.tick_params(top=False, bottom=False, left=False, right=False)


    def __init__(self, **kwargs):
        super(MDBarChart, self).__init__(plt.gcf(), **kwargs)
        self.update()


class ProgressApp(MDApp):
    def build(self):
        return Builder.load_string(kv)


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

嗯,我想早上 4:30 醒来,喝大量的咖啡因会让我的大脑思考得更好。

我更新了 init 方法,如下所示:

    def __init__(self, **kwargs):
        super(MDBarChart, self).__init__(plt.gcf(), **kwargs)
        Clock.schedule_once(lambda *args:self.update())

通过更新,现在我可以更新 KV Lang 文件并且更改反映在 GUI 上。