用类切换tkinter中的窗口

时间:2016-12-17 12:04:22

标签: python-3.x tkinter

在[前一个问题] [1]中收到了来自@ acw1668的完美脚本,用于创建弹出窗口(见下文)。

如何以新窗口不是弹出窗口但只是从一个页面切换到下一个窗口的形式重写(这里不一定需要列表框/ candvas)?

编辑:试图根据@Bryan Oakley的建议修改代码。 我的问题在这里:我没有设法将GUI类中的列表 File "/.spyder-py3/temp.py", line 25, in __init__ frame = F(parent=container, controller=self) TypeError: __init__() missing 1 required positional argument: 'lst' 传递给其他页面类而没有错误消息:

for F in (StartPage, PageOne, PageTwo):
                page_name = F.__name__
                frame = F(parent=container, controller=self,)

                self.frames[page_name] = frame

我在这里缺少什么? 我不明白这里发生了什么:

import tkinter as tk
from tkinter import ttk


class GUI(tk.Tk):

    def __init__(self):

        tk.Tk.__init__(self)
        self.lst = ['a', 'b', 'c']
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, PageOne, PageTwo):
            page_name = F.__name__
            frame = F(parent=container, controller=self,)

            self.frames[page_name] = frame

            # put all of the pages in the same location;
            # the one on the top of the stacking order
            # will be the one that is visible.
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage", self.lst)

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()


    def show_popup(self, page, lst):

        win = page(self, lst)
        win.grab_set()          # make window modal
        self.wait_window(win)   # make window modal




class StartPage(tk.Frame):

    def __init__(self, parent, controller, lst):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.lst = lst
         # ------------------------------------------------------------------- #
        label = tk.Label(self, text="Check this out")                         
        label.pack(pady=10,padx=10)

         # ------------------- create buttons ---------------------------------
        button1 = ttk.Button(self, text="show all",
                             width = 25, command=lambda: 
                                 controller.show_popup(App, self.lst))
        button1.pack(pady=10, padx=10)        
        button2 = ttk.Button(self, text="show page one",
                             width = 25, command=lambda: 
                                 controller.show_frame(PageOne))
        button2.pack(pady=10, padx=10)        


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is page 1")
        label.pack(side="top", fill="x", pady=10)
        button = tk.Button(self, text="Go to the start page",
                           command=lambda: controller.show_frame("StartPage"))
        button.pack()


class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is page 2")
        label.pack(side="top", fill="x", pady=10)
        button = tk.Button(self, text="Go to the start page",
                           command=lambda: controller.show_frame("StartPage"))
        button.pack()

class App(tk.Toplevel):

    def __init__(self, parent, lst):
        tk.Toplevel.__init__(self, parent)
        self.lst = lst
        self.title('This is the pop up window')
        self.geometry('400x200') 
        label = tk.Label(self, text=self.lst) 
        label.pack(side="top", fill="x", pady=10)
        parent.grid_rowconfigure(0, weight = 1)
        parent.grid_columnconfigure(0, weight = 1)

if __name__ == '__main__': 
    app = GUI() 
    app.mainloop()                  

  [1]: http://stackoverflow.com/questions/41181809/how-to-open-and-close-another-window-with-scrollbar-in-tkinter-for-python-3-5/41182843?noredirect=1#comment69580999_41182843

如果有人可以解释,请?

gmail

1 个答案:

答案 0 :(得分:1)

您的类初始值设定项定义如下:

class StartPage(tk.Frame):
    def __init__(self, parent, controller, lst):

为了创建此类的实例,它需要三个参数(加self):parentcontrollerlst

现在,让我们看看你是如何创建实例的:

frame = F(parent=container, controller=self,)

请注意您拥有parent并拥有controller的方式,但是您没有为lst传递任何内容。这就是为什么错误声明“缺少1个必需的位置参数:'lst'” - 因为你实际上缺少一个名为“lst”的必需参数。

要解决此问题,您只需提供此额外参数即可。例如:

frame = F(parent=container, controller=self, lst=self.lst)

然而,你可能不应该这样做。您复制的这个小代码块的体系结构使得可以从任何“页面”类访问GUI类的值,而无需进行任何额外的工作。

因为此变量是GUI类的属性,并且您将对GUI类的实例的引用传递给每个“页面”(controller属性),您可以随时访问此数据,而无需在构建时传递它。您可以从__init__和您创建页面的位置删除它(即:在修改之前返回原始代码),然后只需在需要值时使用self.controller.lst

例如:

class SomePage(tk.Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        ...
    def some_function(self):
        print("The value of 'lst' is:", self.controller.lst)