我正在尝试重现经典的'switching between frames'示例。我正在尝试包括几个tkk小部件,并使用.grid()
代替.pack()
。切换帧效果很好,但是,我在tkk小部件中遇到了“ raising
”问题。
import Tkinter as tk
import ttk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2TkAgg)
import matplotlib.pyplot as plt
import numpy as np
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.grid()
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.window = parent
label = tk.Label(self, text="This is the start page")
label.grid(pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button1.grid()
self.create_widgets()
def create_widgets(self):
# Create some room around all the internal frames
self.window['padx'] = 0
self.window['pady'] = 0
frame1 = ttk.Frame(self.window, relief=tk.RIDGE)
frame1.grid(row=0, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
frame2 = ttk.Frame(self.window, relief=tk.RIDGE)
frame2.grid(row=1, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
p = self.Plot(frame1, frame2)
class Plot():
def __init__(self, parent1, parent2):
self.parent1 = parent1
self.parent2 = parent2
canvas = self.plot()
self.plot_toolbar(canvas)
def plot(self):
fig, ax = plt.subplots()
fig.tight_layout()
## plot of sin displayed on page one
p = plt.plot(np.sin(np.arange(10)))
canvas = FigureCanvasTkAgg(fig, self.parent1)
canvas.draw()
return(canvas)
def plot_toolbar(self, canvas):
toolbar = NavigationToolbar2TkAgg(canvas, self.parent2)
toolbar.update()
canvas.get_tk_widget().grid(row=1, column=1)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.window = parent
label = tk.Label(self, text="This is page 1")
label.grid(pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.grid()
self.create_widgets()
def create_widgets(self):
# Create some room around all the internal frames
self.window['padx'] = 0
self.window['pady'] = 0
frame1 = ttk.Frame(self.window, relief=tk.RIDGE)
frame1.grid(row=0, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
frame2 = ttk.Frame(self.window, relief=tk.RIDGE)
frame2.grid(row=1, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
p = self.Plot(frame1, frame2)
class Plot():
def __init__(self, parent1, parent2):
self.parent1 = parent1
self.parent2 = parent2
canvas = self.plot()
self.plot_toolbar(canvas)
def plot(self):
fig, ax = plt.subplots()
fig.tight_layout()
## plot of a cosin displayed on PageOne
p = plt.plot(np.cos(np.arange(10)))
canvas = FigureCanvasTkAgg(fig, self.parent1)
canvas.draw()
return(canvas)
def plot_toolbar(self, canvas):
toolbar = NavigationToolbar2TkAgg(canvas, self.parent2)
toolbar.update()
canvas.get_tk_widget().grid(row=1, column=1)
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
如果运行此命令,您会发现我可以完美地从StartPage和PageOne更新Pages,但是绘图不会从Sin变为Cosin!为什么?
答案 0 :(得分:0)
已解决:
我需要将tkk.Frames
或StartPage.self
作为PageOne.self
传递给parent
,而不是将SampleApp容器传递到tkk.Frames
中!
以下按我希望的方式工作:
import Tkinter as tk
import ttk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2TkAgg)
import matplotlib.pyplot as plt
import numpy as np
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.grid()
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.window = parent
label = tk.Label(self, text="This is the start page")
label.grid(pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button1.grid()
self.create_widgets()
def create_widgets(self):
# Create some room around all the internal frame
frame1 = ttk.Frame(self, relief=tk.RIDGE)
frame1.grid(row=0, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
frame2 = ttk.Frame(self, relief=tk.RIDGE)
frame2.grid(row=1, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
p = self.Plot(frame1, frame2)
class Plot():
def __init__(self, parent1, parent2):
self.parent1 = parent1
self.parent2 = parent2
canvas = self.plot()
self.plot_toolbar(canvas)
def plot(self):
fig, ax = plt.subplots()
fig.tight_layout()
p = plt.plot(np.exp(np.linspace(0,10,100)))
canvas = FigureCanvasTkAgg(fig, self.parent1)
canvas.draw()
return(canvas)
def plot_toolbar(self, canvas):
toolbar = NavigationToolbar2TkAgg(canvas, self.parent2)
toolbar.update()
canvas.get_tk_widget().grid(row=0, column=0)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.window = parent
label = tk.Label(self, text="This is page 1")
label.grid(pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.grid()
self.create_widgets()
def create_widgets(self):
# Create some room around all the internal frames
frame1 = ttk.Frame(self, relief=tk.RIDGE)
frame1.grid(row=0, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
frame2 = ttk.Frame(self, relief=tk.RIDGE)
frame2.grid(row=1, column=1, sticky=tk.E + tk.W + tk.N + tk.S, padx=0, pady=0)
p = self.Plot(frame1, frame2)
class Plot():
def __init__(self, parent1, parent2):
self.parent1 = parent1
self.parent2 = parent2
canvas = self.plot()
self.plot_toolbar(canvas)
def plot(self):
fig, ax = plt.subplots()
fig.tight_layout()
p = plt.plot(np.sin(np.linspace(0,10,100)))
canvas = FigureCanvasTkAgg(fig, self.parent1)
canvas.draw()
return(canvas)
def plot_toolbar(self, canvas):
toolbar = NavigationToolbar2TkAgg(canvas, self.parent2)
toolbar.update()
canvas.get_tk_widget().grid(row=0, column=0)
if __name__ == "__main__":
app = SampleApp()
app.mainloop()