如何通过使用另一个类来连接和断开matplotlib的事件处理程序?

时间:2019-10-10 12:30:41

标签: python matplotlib tkinter

我目前正在使用class MainApplication创建GUI并加载图像的程序。第二个class Func包含用于连接或断开matplotlib的事件处理程序的函数以及回调函数on_press

一个问题是我在类MainApplication中使用self.fig的类对象self.axFunc。但是我只收到一个TypeError: init ()缺少2个必需的位置参数:“ fig”和“ ax”。

通常如何从另一个类操纵一个类的对象?

MainApplication.py

import sys
if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.image as mpimg  
from Func import Func  

class MainApplication(Tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        Tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        parent.iconify
        parent.grid_rowconfigure(1, weight=1)
        parent.grid_columnconfigure(1, weight=1)

        top_frame = Tk.Frame(parent)
        top_frame.grid(row=0)       
        mid_frame = Tk.Frame(parent)
        mid_frame.grid(row=1)

        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        self.ax.set_aspect('equal')       
        canvas = FigureCanvasTkAgg(self.fig, mid_frame)
        canvas.get_tk_widget().grid(row=0, column=0, sticky="nsew")
        canvas._tkcanvas.grid(row=0, column=0, sticky="nsew")        
        img = mpimg.imread('stinkbug.png')
        self.ax.imshow(img)
        self.fig.canvas.draw()

        self.var1 = Tk.IntVar()
        chkbx1 = Tk.Checkbutton(top_frame, text='connect', variable=self.var1, command=self.de_activate)
        chkbx1.grid(row=0, column=0, sticky="w")

    def de_activate(self):
        fc = Func()
        fc.__init__(self.fig, self.ax)
        print('checkbutton: '+str(self.var1.get()))
        if self.var1.get() == 1:
            fc.connect()
            print('on_press connected (cid='+str(self.cidpress)+')')
        else:
            fc.disconnect()
            print('on_press disconnected (cid='+str(self.cidpress)+')')

if __name__ == '__main__':
    root = Tk.Tk()
    MainApplication(root).grid(row=0, column=0, sticky="nsew")
    root.mainloop()

Func.py

class Func():
    def __init__(self, fig, ax):
        self.fig = fig
        self.ax = ax

    def connect(self):
        self.cidpress = self.fig.canvas.mpl_connect('button_press_event', self.on_press)

    def disconnect(self):
        self.fig.canvas.mpl_disconnect(self.cidpress)

    def on_press(self, event):
        if event.inaxes != self.ax: return
        print('button pressed')

1 个答案:

答案 0 :(得分:1)

正确的版本看起来像

import sys
if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.image as mpimg  
#from Func import Func  

class Func():
    def __init__(self, fig, ax):
        self.fig = fig
        self.ax = ax

    def connect(self):
        self.cidpress = self.fig.canvas.mpl_connect('button_press_event', self.on_press)

    def disconnect(self):
        self.fig.canvas.mpl_disconnect(self.cidpress)

    def on_press(self, event):
        if event.inaxes != self.ax: return
        print('button pressed')

class MainApplication(Tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        Tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        parent.iconify
        parent.grid_rowconfigure(1, weight=1)
        parent.grid_columnconfigure(1, weight=1)

        top_frame = Tk.Frame(parent)
        top_frame.grid(row=0)       
        mid_frame = Tk.Frame(parent)
        mid_frame.grid(row=1)


        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        self.fc = Func(self.fig, self.ax)

        self.ax.set_aspect('equal')       
        canvas = FigureCanvasTkAgg(self.fig, mid_frame)
        canvas.get_tk_widget().grid(row=0, column=0, sticky="nsew")
        canvas._tkcanvas.grid(row=0, column=0, sticky="nsew")        
        img = mpimg.imread('house.png')
        self.ax.imshow(img)
        self.fig.canvas.draw()

        self.var1 = Tk.IntVar()
        chkbx1 = Tk.Checkbutton(top_frame, text='connect', variable=self.var1, command=self.de_activate)
        chkbx1.grid(row=0, column=0, sticky="w")

    def de_activate(self):

        print('checkbutton: '+str(self.var1.get()))
        if self.var1.get() == 1:
            self.fc.connect()
            print('on_press connected (cid='+str(self.fc.cidpress)+')')
        else:
            self.fc.disconnect()
            print('on_press disconnected (cid='+str(self.fc.cidpress)+')')

if __name__ == '__main__':
    root = Tk.Tk()
    MainApplication(root).grid(row=0, column=0, sticky="nsew")
    root.mainloop()