在[前一个问题] [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
答案 0 :(得分:1)
您的类初始值设定项定义如下:
class StartPage(tk.Frame):
def __init__(self, parent, controller, lst):
为了创建此类的实例,它需要三个参数(加self
):parent
,controller
和lst
。
现在,让我们看看你是如何创建实例的:
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)