我一直在尝试为按钮执行命令以绘制matplotlib图形。我已经看过这个post。但这并没有太大帮助,因为该示例在一个类中包含了所有内容。我正在努力将来自不同类的对象链接在一起。
要执行的命令是针对button2
中的class EntryButton
。情节本身是在class CalcPlot
中制作的。最后,我希望绘图显示为class PlotWindow
的实例。
我尝试设置command=PlotWindow.plot
,但这不起作用。另外,我不确定该方法应位于哪个类中。继承可以起作用,但是由于类已经从Frame
类继承,因此我找不到如何设置它的方法。
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()
答案 0 :(得分:0)
您不仅可以在命令中调用对象,还必须在要绘制的类中已经设置了对象。像在MainWindow(Frame)中一样,您已经具有EntryButton和PlotWindow,但是PlotWindow没有不是EntryButton内的对象。因此,您需要向EntryButton类添加一个PlotWindow,如
plot_frame= PlotWindow(self)
在MainWindow中,然后在按钮内部调用命令,如
command= plot_frame.plot()
或者您将需要找到某种方法来使EntryButton从MainWindow继承PlotWindow事物,但这可能与您想要的东西有所不同。
答案 1 :(得分:0)
您可以使用控制器对象将两者链接在一起。这是我一些旧代码的摘录:
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_controller不需要知道如何制作图形,只需将数据传递到控制器即可。 display_controller不知道数据来自何处,只是将其转换为图形。