Нарисуйте рисунок Matplotlib в Tkinter по нажатию кнопки - PullRequest
1 голос
/ 27 марта 2019

Я пытался выполнить команду для кнопки для построения фигуры matplotlib.Я был над этим постом .Но это не совсем помогает, так как в примере все в одном классе.Я изо всех сил пытаюсь связать объекты из разных классов вместе.Команда для выполнения предназначена для button2 в class EntryButton.Сам сюжет выполнен в class CalcPlot.И, наконец, я хочу, чтобы график отображался как экземпляр class PlotWindow.

. Я пытался установить command=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()

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Вы можете использовать объект контроллера, чтобы связать их вместе.Вот фрагмент из моего старого кода:

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))

Ключ-контроллер не должен знать, КАК сделаны графики,он просто передает данные в контроллер.Display_controller не знает, откуда поступают данные, он просто превращает их в график.

0 голосов
/ 27 марта 2019

Вы не можете просто вызвать объект в команде, вы должны иметь объект, уже настроенный в классе, в котором вы пытаетесь построить. Как и в MainWindow (Frame), у вас уже есть EntryButton и PlotWindow, но PlotWindow не не является объектом внутри EntryButton. Поэтому вам нужно добавить PlotWindow в класс EntryButton, например

plot_frame= PlotWindow(self)

в главном окне, а затем вызовите команду внутри кнопки, например

 command= plot_frame.plot()

Или вам нужно будет найти способ заставить EntryButton наследовать вещи PlotWindow от MainWindow, но это может отличаться от того, что вы хотите из этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...