提升包含小部件的TK框架

时间:2018-06-20 16:10:54

标签: python tkinter

我正在尝试重现经典的'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!为什么?

1 个答案:

答案 0 :(得分:0)

已解决:

我需要将tkk.FramesStartPage.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()
相关问题