Python 单击按钮在tkinter中绘制matplotlib图形

Python 单击按钮在tkinter中绘制matplotlib图形,python,tkinter,Python,Tkinter,我一直在尝试执行一个按钮的命令来绘制matplotlib图形。我已经讨论过了。但这并没有太大的帮助,因为示例将所有内容都放在一个类中。我正在努力将不同类的对象链接在一起。 要执行的命令用于class EntryButton中的button2。绘图本身是在类CalcPlot中绘制的。最后,我希望绘图显示为类PlotWindow的实例 我已尝试设置命令=PlotWindow.plot,但不起作用。我也不确定该方法应该在哪个类中。继承可以工作,但我找不到如何设置它,因为类已经从Frameclass继承

我一直在尝试执行一个按钮的命令来绘制matplotlib图形。我已经讨论过了。但这并没有太大的帮助,因为示例将所有内容都放在一个类中。我正在努力将不同类的对象链接在一起。 要执行的命令用于
class EntryButton
中的
button2
。绘图本身是在
类CalcPlot
中绘制的。最后,我希望绘图显示为
类PlotWindow
的实例

我已尝试设置
命令=PlotWindow.plot
,但不起作用。我也不确定该方法应该在哪个类中。继承可以工作,但我找不到如何设置它,因为类已经从
Frame
class继承了

from tkinter import *
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
matplotlib.use('TkAgg')


class MainWindow(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.config(bg='blue')
        self.pack(side=TOP, fill=BOTH, expand=True)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        #frames
        entry_frame = EntryButton(self)
        plot_frame = PlotWindow(self)

x1 = 1
x2 = 2
y1 = 1
y2 = 2


class EntryButton(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.config(width=600, height=400, bg='#ff6600')
        self.place(x=0, y=0)

        self.entry1 = Entry(self, width=10)
        self.entry1.insert(0, '0')
        self.entry1.place(x=110, y=40, anchor=W)

        self.entry2 = Entry(self, width=10)
        self.entry2.insert(0, '0')
        self.entry2.place(x=180, y=40, anchor=W)

        self.entry3 = Entry(self, width=10)
        self.entry3.insert(0, '0')
        self.entry3.place(x=110, y=65, anchor=W)

        self.entry4 = Entry(self, width=10)
        self.entry4.insert(0, '0')
        self.entry4.place(x=180, y=65, anchor=W)

        label1 = Label(self, text='x coord.', font='arial 10 bold', bg='#ff6600')
        label1.place(x=50, y=40, anchor=W)

        label2 = Label(self, text='y coord.', font='arial 10 bold', bg='#ff6600')
        label2.place(x=50, y=65, anchor=W)

        button1 = Button(self, text='enter', width=8, command=self.set_values)
        button1.place(x=180, y=100, anchor=W)

        button2 = Button(self, text='plot', width=8, command=PlotWindow.plot)
        button2.place(x=180, y=140, anchor=W)

    def set_values(self):
        global x1, x2, y1, y2
        x1 = int(self.entry1.get())
        x2 = int(self.entry2.get())
        y1 = int(self.entry3.get())
        y2 = int(self.entry4.get())

    def plot(self):         #possibly the function should be here
        pass


class CalcClass:
    def __init__(self, parent):
        fig = Figure(figsize=(6, 4))
        axes = fig.add_subplot(1, 1, 1)
        global x1, x2, y1, y2
        axes.plot([x1, x2], [y1, y2])

        canvas = FigureCanvasTkAgg(fig, parent)
        canvas.draw()
        canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=True)


class PlotWindow(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.config(width=600, height=400, bg='yellow')
        self.place(x=600, y=0)

    def plot(self):
        plot = CalcClass(self)


if __name__ == '__main__':
    root = Tk()
    root.title('Frost Lite')
    app = MainWindow(root)
    root.geometry('1200x400+2000+800')
    root.resizable(False, False)
    root.mainloop()

不能只在命令中调用对象,必须在试图绘制的类中设置对象。与在主窗口(框架)中一样,您已经有EntryButton和PlotWindow,但PlotWindow不是EntryButton内部的对象。因此,您需要向EntryButton类添加一个PlotWindow,如

plot_frame= PlotWindow(self)
在主窗口中,然后调用按钮内的命令,如

 command= plot_frame.plot()

或者,您需要找到某种方法使EntryButton从主窗口继承PlotWindow内容,但这可能不同于您希望从中获得的内容。

您不能仅在命令中调用对象,您必须在尝试打印的类中设置对象。与在主窗口(框架)中一样,您已经有EntryButton和PlotWindow,但PlotWindow不是EntryButton内部的对象。因此,您需要向EntryButton类添加一个PlotWindow,如

plot_frame= PlotWindow(self)
在主窗口中,然后调用按钮内的命令,如

 command= plot_frame.plot()

或者,您需要找到某种方法使EntryButton从主窗口继承PlotWindow内容,但这可能与您希望的有所不同。

您可以使用控制器对象将两者链接在一起。下面是我的一些旧代码的一个片段:

class gui(tk.Tk):
    def __init__(self, char, *args, **kwargs):
        self.display_cont = display_controller( leftSide, self)
        keyboard = key_controller( rightSide, self, height=474, width=300)

class display_controller(tk.Frame):
    def bar_chart(self, x, y, xlabel, ylabel, title):
        self.frames["matplotlib_display"].bar_chart(x, y, xlabel, ylabel, title)
        self.show_frame("matplotlib_display")

class matplotlib_display(tk.Frame):
    def bar_chart(self, x, y, xlabel, ylabel, title):
        self.fig.clf()
        graph = self.fig.add_subplot(1,1,1)
        x_fill = [i for i in range(len(x))]
        graph.bar(x_fill,y)

        graph.set_title(title)
        graph.set_xlabel(xlabel)
        graph.set_ylabel(ylabel)

        graph.set_xticks(range(len(x)))
        graph.set_xticklabels(x)

class key_controller(tk.Frame):
    def show_production(self, entity):
        display_cont = self.root.get_display_cont()
        xy = entity.getProduction()
        products = [d.getMaterials()[xy[0][i]] for i in range(len(xy[0]))]
        display_cont.bar_chart(products, xy[1], "Products", "Crafted", entity.name + " Production")
然后,您可以制作如下按钮:

production = tk.Button(self, text="[c] Crafted", font=BUTTON_FONT, command=lambda: controller.show_production(self.business))

key_控制器不需要知道图形是如何生成的,它只是将数据传递给控制器。显示控制器不知道数据来自何处,它只是将数据转换成图形

可以使用控制器对象将两者链接在一起。下面是我的一些旧代码的一个片段:

class gui(tk.Tk):
    def __init__(self, char, *args, **kwargs):
        self.display_cont = display_controller( leftSide, self)
        keyboard = key_controller( rightSide, self, height=474, width=300)

class display_controller(tk.Frame):
    def bar_chart(self, x, y, xlabel, ylabel, title):
        self.frames["matplotlib_display"].bar_chart(x, y, xlabel, ylabel, title)
        self.show_frame("matplotlib_display")

class matplotlib_display(tk.Frame):
    def bar_chart(self, x, y, xlabel, ylabel, title):
        self.fig.clf()
        graph = self.fig.add_subplot(1,1,1)
        x_fill = [i for i in range(len(x))]
        graph.bar(x_fill,y)

        graph.set_title(title)
        graph.set_xlabel(xlabel)
        graph.set_ylabel(ylabel)

        graph.set_xticks(range(len(x)))
        graph.set_xticklabels(x)

class key_controller(tk.Frame):
    def show_production(self, entity):
        display_cont = self.root.get_display_cont()
        xy = entity.getProduction()
        products = [d.getMaterials()[xy[0][i]] for i in range(len(xy[0]))]
        display_cont.bar_chart(products, xy[1], "Products", "Crafted", entity.name + " Production")
然后,您可以制作如下按钮:

production = tk.Button(self, text="[c] Crafted", font=BUTTON_FONT, command=lambda: controller.show_production(self.business))
key_控制器不需要知道图形是如何生成的,它只是将数据传递给控制器。显示控制器不知道数据来自何处,它只是将数据转换成图形