使用kivy按钮触发event.canvas.draw()

时间:2019-07-13 14:35:01

标签: python matplotlib kivy

我试图在一个kivy应用程序中设置一个matplotlib图,该应用程序从kivy按钮中获取命令,但是在按钮触发方法时很难触发event.canvas.draw()函数来更新显示的图。关于如何解决这个问题的任何想法?现在,我已经设置了按键功能来切换功能,但是我宁愿让“ button2”触发事件。

from kivy.uix.boxlayout import BoxLayout
from matplotlib import pyplot as plt
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvas
import numpy
from kivy.app import App
from kivy.uix.button import Button


class Builder(App):
    main_layout = BoxLayout(orientation='vertical')
    top_layout = BoxLayout()
    bottom_layout = BoxLayout()
    main_layout.add_widget(top_layout)
    main_layout.add_widget(bottom_layout)

    def build(self):
        self.top_layout.add_widget(self.get_fc())
        self.bottom_layout.add_widget(Button(text='button1'))
        #self.bottom_layout.add_widget(Button(text='button2', on_press=self.pull_plots()))
        return self.main_layout

    def add_plot(self, event):

        if isinstance(event.ydata, (int, float, numpy.float64)) is False or isinstance(event.xdata, (int, float, numpy.float64)) is False or (event.ydata, event.xdata) != (
        event.ydata, event.xdata): return

        ax.plot(event.xdata, event.ydata, 'o', color='r')[0]
        event.canvas.draw()

    def pull_plots(self, event):
        try:
            del ax.lines[-1]
        except:
            pass
        event.canvas.draw()

    def get_fc(self):
        global fig1, ax
        fig1 = plt.figure()
        ax = fig1.add_subplot(111)
        ax.plot([], [])
        wid = FigureCanvas(fig1)
        fig1.canvas.mpl_connect('button_press_event', self.add_plot)
        fig1.canvas.mpl_connect('key_press_event', self.pull_plots)

        return wid


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

1 个答案:

答案 0 :(得分:1)

解决方案

有两种解决方法。第一种方法使用fig1,第二种方法使用Kivy ObjectProperty。

方法1-使用图1

  • event.canvas.draw()替换为fig1.canvas.draw()
  • fig1.canvas.draw()之后的try块中调用del ax.lines[-1],即,如果有任何更改,请重新绘制画布。
  • 取消注释'button2'
  • 用方法event中的instance替换参数pull_plots()

摘要

class Builder(App):
    ...

    def build(self):
        ...
        self.bottom_layout.add_widget(Button(text='button2', on_press=self.pull_plots))
        ...

    def pull_plots(self, instance):
        try:
            del ax.lines[-1]
            fig1.canvas.draw()    # re-draw canvas
        except:
            pass

方法2-使用Kivy ObjectProperty

  • 方法时,将matplotlib鼠标事件保存到Kivy ObjectPropertympl_mouse_event add_plot()被调用
  • event.canvas.draw()替换为self.mpl_mouse_event.canvas.draw()
  • fig1.canvas.draw()之后的try块中调用del ax.lines[-1],即,如果有任何更改,请重新绘制画布。
  • 取消注释'button2'
  • 用方法event中的instance替换参数pull_plots()

摘要

from kivy.properties import ObjectProperty


class Builder(App):
    mpl_mouse_event = ObjectProperty(None)
    ...

    def build(self):
        ...
        self.bottom_layout.add_widget(Button(text='button2', on_press=self.pull_plots))
        ...

    def add_plot(self, event):
        self.mpl_mouse_event = event
        ...

    def pull_plots(self, instance):
        try:
            del ax.lines[-1]

            if self.mpl_mouse_event is not None:   
                self.mpl_mouse_event.canvas.draw()    # re-draw canvas
        except:
            pass