问题描述
我正在尝试重现经典的在帧之间切换" 示例.我正在尝试包含几个 tkk 小部件并使用 .grid()
而不是 .pack()
.切换框架效果很好,但是,我在提升
"tkk 小部件时遇到了麻烦.
I am trying to reproduce the classic 'switching between frames' example. I am trying to include a couple of tkk widgets and have used .grid()
instead of .pack()
. Switching the frames works perfectly, however, I am having troubles "raising
" the tkk widgets.
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!为什么?
If you run this you will find that I can perfectly update the Pages from StartPage And PageOne, but the plot does not change from Sin to Cosin! Why?
推荐答案
已解决:
我不需要将 SampleApp 容器传递到 tkk.Frames
中,而是需要传递 StartPage.self
或 PageOne.self
> 作为 tkk.Frames
的 parent
!
Instead of passing the SampleApp container into the tkk.Frames
, I would have needed to put pass the StartPage.self
or PageOne.self
as parent
for the 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()
这篇关于提升包含小部件的 TK 框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!