我一直在研究Tkinter并且发现在不同帧之间传递值时遇到问题,因此我使用this tutorial here提供的“共享数据”解决方案跟随Bryan Oakley并将其添加到我自己的代码中。 除非我无法将“共享数据”字典中的值设置为按钮上的命令。
下面的代码中的一些注释概述了问题。如果我只是尝试在我的选择页面的init期间更改变量,它会正常更改。但是将它放在lambda中意味着字典变量根本不会改变。尝试使用def作为按钮命令有其自身的复杂性。
import tkinter as tk
import tkinter.ttk as ttk
# from tkinter import messagebox
TITLE_FONT = ("Segoe UI Light", 22)
SUBTITLE_FONT = ("Segoe UI Light", 12)
window_size = [300, 200]
resistors = []
choice = "default"
class RegApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.iconbitmap(self, default="test.ico")
tk.Tk.wm_title(self, "Test")
self.shared_data = {
"choice": tk.StringVar(),
}
container = tk.Frame(self, width=window_size[0], height=window_size[1])
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 panels:
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="NSEW")
self.show_frame(WelcomePage)
def show_frame(self, container):
frame = self.frames[container]
frame.tkraise()
class WelcomePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
title_label = ttk.Label(self, text="Welcome", font=TITLE_FONT)
subtitle_label = ttk.Label(self, text="Let's run some numbers.", font=SUBTITLE_FONT)
start_button = ttk.Button(self, text="Begin", width=24, command=lambda: controller.show_frame(ChoicePage))
title_label.pack(pady=(40, 5))
subtitle_label.pack(pady=(0, 10))
start_button.pack()
class ChoicePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.controller.shared_data["choice"].set("test2") # Here, the variable is set fine
title_label = ttk.Label(self, text="Is your resistor network \nin series or parallel?", font=SUBTITLE_FONT,
justify=tk.CENTER)
series_button = ttk.Button(self, text="Series", width=24,
command=lambda: [self.controller.shared_data["choice"].set("series"), controller.show_frame(ValuePage)])
# But when I use it in a lambda, the variable doesn't even seem to set at all. It switches to the next page and has the value ""
parallel_button = ttk.Button(self, text="Parallel", width=24,
command=lambda: controller.show_frame(ValuePage))
title_label.pack()
series_button.pack()
parallel_button.pack()
# TODO Make the user select between 'series' and 'parallel'
class ValuePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
title_label = ttk.Label(self, text=self.controller.shared_data["choice"].get(), font=SUBTITLE_FONT,
justify=tk.CENTER)
title_label.pack()
panels = [WelcomePage, ChoicePage, ValuePage]
app = RegApp()
app.resizable(False, False)
app.geometry('{}x{}'.format(window_size[0], window_size[1]))
app.mainloop()
答案 0 :(得分:1)
在帧之间传递数据并不太难。有两种方法我喜欢这样做。
方法1:
class ThirdName(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
现在只需说出:
self.data = "this is some data"
现在当你在另一个框架中时,你可以这样称呼它:
print(ThirdName.data)
>>> "this is some data"
第二种方式是将它发送到这样的地方:
value_1 = 'Richard'
bobby_def(value_1, 42, 'this is some text')
...
def bobby_def(name, number, text)
print(text)
or...
return(name, number, text)
鲍比将获得数据:)
确定....第二点......在帧之间移动可以通过以下方式完成:
self.button_to_go_to_home_page = tk.Button(self, text='Third\nPage', font=Roboto_Normal_Font,
command=lambda: self.controller.show_frame(ThirdName),
height=2, width=12, bd = 0, activeforeground=active_fg, activebackground=active_bg, highlightbackground=border_colour,
foreground=bg_text_colour, background=background_deselected)
self.button_to_go_to_home_page.place(x=20, y=280)
**用这样的东西设置框架:
class SecondName(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
是的,self.controller方法也是我使用的方法,在一帧中将大量数据放在一起很好。
答案 1 :(得分:0)
为什么使用'controller'代替'self.controller'?在构造函数的开头指定'self.controller'然后使用'controller'代替,这有点令人困惑。也许变量阴影会导致你的问题。