Tkinter 文本小部件 - 控制器中的变量
Tkinter Text Widget - variable in controller
我有一个带有多个框架和不同小部件的小型 GUI。我能够使所有变量成为全局变量,并在控制器中可用,但我被困在文本小部件上。有什么建议吗?
这里只是举个例子,文本小部件在class“PageOne”,打印功能在“PageTwo”
import tkinter as tk
from tkinter import *
from tkinter import ttk
LARGE_FONT=("Verdana", 12)
class Movies(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self,*args, **kwargs)
tk.Tk.wm_title(self, "Movie I like")
tk.Tk.wm_geometry(self, "500x500")
container=tk.Frame(self)
container.pack(side="top", fill="both", expand="True")
self.app_data = {"movie": StringVar(),
"popcorn": StringVar(),
"monday": BooleanVar(),
"tuesday": BooleanVar(),
"wednesday": BooleanVar(),
"thursday": BooleanVar(),
"friday": BooleanVar(),
"saturday": BooleanVar(),
"sunday": BooleanVar(),
}
self.frames={}
for F in (StartPage, PageOne, PageTwo):
frame= F(container, self)
self.frames[F]= frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame=self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
s = ttk.Style()
s.configure('my.TButton', font=('Verdana', 8))
label=tk.Label(self, text="Home Page", font=LARGE_FONT)
label.pack(pady=10, padx=30)
label1=tk.Label(self, text="When are you available?")
label1.pack()
#CheckButton
ttk.Checkbutton(self, text='Monday', variable=self.controller.app_data["monday"]).pack()
ttk.Checkbutton(self, text='Tuesday', variable=self.controller.app_data["tuesday"]).pack()
ttk.Checkbutton(self, text='Wednesday', variable=self.controller.app_data["wednesday"]).pack()
ttk.Checkbutton(self, text='Thursday', variable=self.controller.app_data["thursday"]).pack()
ttk.Checkbutton(self, text='Friday', variable=self.controller.app_data["friday"]).pack()
ttk.Checkbutton(self, text='Saturday', variable=self.controller.app_data["saturday"]).pack()
ttk.Checkbutton(self, text='Sunday', variable=self.controller.app_data["sunday"]).pack()
button_load=ttk.Button(self, text="Kind of Movie ", width=30, style='my.TButton',
command= lambda: controller.show_frame(PageOne))
button_load.pack(padx=30)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
mybutton=ttk.Radiobutton(self, text='Drama', variable=self.controller.app_data["movie"], value="Drama").grid(column=1,row=1, sticky=W, padx=10)
mybutton1=ttk.Radiobutton(self, text='Comedy', variable=self.controller.app_data["movie"], value="Comedy").grid(column=2,row=1, sticky=W, padx=10)
globals()['user_message_entry'] = tk.Text(self, height=10, width=60).grid(column=1, row= 3, padx=5)
button_next=ttk.Button(self, text="Next >> ", width=30, style='my.TButton',
command= lambda: controller.show_frame(PageTwo)).grid(column=3, row= 10, padx=5)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
body = globals()['user_message_entry'].get("1.0", "end")
mybutton2=ttk.Radiobutton(self, text='Salty', variable=self.controller.app_data["popcorn"], value="Salty").grid(column=1,row=1, sticky=W, padx=10)
mybutton3=ttk.Radiobutton(self, text='Sweet', variable=self.controller.app_data["popcorn"], value="Sweet").grid(column=2,row=1, sticky=W, padx=10)
def save_info():
pop_info=self.controller.app_data["popcorn"].get()
movie_info=self.controller.app_data["movie"].get()
week=["monday", "tuesday", "wednesday","thursday","friday","saturday","sunday"]
print("you like " + movie_info + " and you would like " + pop_info +" popcorn")
print("This is the body" + body)
test=len(week)
for i in range (0, test):
if self.controller.app_data[week[i]].get() == True:
print(week[i])
button_submit=ttk.Button(self, text="Submit", width=15,
command=save_info).grid(column=3, row= 10, padx=5)
app=Movies()
app.mainloop()
一种解决方案是像保存其他内容一样将小部件存储在控制器中。
例如:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.controller.app_data["user_message_entry"] = Text(self, height=10, width=60)
...
然后,要获取值,它类似于获取其他变量的方式:
body = self.controller.app_data['user_message_entry'].get("1.0", "end")
另一种访问它的方法是为您的控制器提供一个功能,该功能将 return 一个页面。然后,您可以使用 returned 页面访问它。
例如,首先在控制器中添加一个函数到return一个页面:
class Movies(tk.Tk):
...
def get_page(self, page_class):
return self.frames[page_class]
...
接下来,确保文本小部件是一个实例变量:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.user_message_entry' = tk.Text(self, height=10, width=60).grid(column=1, row= 3, padx=5)
...
最后,在控制器中使用该函数获取另一个页面,然后从那里获取文本小部件:
page = self.controller.get_page(PageOne)
body = page.textuser_message_entry.get("1.0", "end")
上面介绍了如何从多个地方访问文本小部件。但是,您还有另一个问题,因为您编写的代码试图在创建小部件几毫秒后从小部件中获取文本。您需要等到用户有机会在获取数据之前输入小部件。
例如,您需要将 body = page.textuser_message_entry.get("1.0", "end")
移动到 save_info
函数内部。
我有一个带有多个框架和不同小部件的小型 GUI。我能够使所有变量成为全局变量,并在控制器中可用,但我被困在文本小部件上。有什么建议吗?
这里只是举个例子,文本小部件在class“PageOne”,打印功能在“PageTwo”
import tkinter as tk
from tkinter import *
from tkinter import ttk
LARGE_FONT=("Verdana", 12)
class Movies(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self,*args, **kwargs)
tk.Tk.wm_title(self, "Movie I like")
tk.Tk.wm_geometry(self, "500x500")
container=tk.Frame(self)
container.pack(side="top", fill="both", expand="True")
self.app_data = {"movie": StringVar(),
"popcorn": StringVar(),
"monday": BooleanVar(),
"tuesday": BooleanVar(),
"wednesday": BooleanVar(),
"thursday": BooleanVar(),
"friday": BooleanVar(),
"saturday": BooleanVar(),
"sunday": BooleanVar(),
}
self.frames={}
for F in (StartPage, PageOne, PageTwo):
frame= F(container, self)
self.frames[F]= frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame=self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
s = ttk.Style()
s.configure('my.TButton', font=('Verdana', 8))
label=tk.Label(self, text="Home Page", font=LARGE_FONT)
label.pack(pady=10, padx=30)
label1=tk.Label(self, text="When are you available?")
label1.pack()
#CheckButton
ttk.Checkbutton(self, text='Monday', variable=self.controller.app_data["monday"]).pack()
ttk.Checkbutton(self, text='Tuesday', variable=self.controller.app_data["tuesday"]).pack()
ttk.Checkbutton(self, text='Wednesday', variable=self.controller.app_data["wednesday"]).pack()
ttk.Checkbutton(self, text='Thursday', variable=self.controller.app_data["thursday"]).pack()
ttk.Checkbutton(self, text='Friday', variable=self.controller.app_data["friday"]).pack()
ttk.Checkbutton(self, text='Saturday', variable=self.controller.app_data["saturday"]).pack()
ttk.Checkbutton(self, text='Sunday', variable=self.controller.app_data["sunday"]).pack()
button_load=ttk.Button(self, text="Kind of Movie ", width=30, style='my.TButton',
command= lambda: controller.show_frame(PageOne))
button_load.pack(padx=30)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
mybutton=ttk.Radiobutton(self, text='Drama', variable=self.controller.app_data["movie"], value="Drama").grid(column=1,row=1, sticky=W, padx=10)
mybutton1=ttk.Radiobutton(self, text='Comedy', variable=self.controller.app_data["movie"], value="Comedy").grid(column=2,row=1, sticky=W, padx=10)
globals()['user_message_entry'] = tk.Text(self, height=10, width=60).grid(column=1, row= 3, padx=5)
button_next=ttk.Button(self, text="Next >> ", width=30, style='my.TButton',
command= lambda: controller.show_frame(PageTwo)).grid(column=3, row= 10, padx=5)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
body = globals()['user_message_entry'].get("1.0", "end")
mybutton2=ttk.Radiobutton(self, text='Salty', variable=self.controller.app_data["popcorn"], value="Salty").grid(column=1,row=1, sticky=W, padx=10)
mybutton3=ttk.Radiobutton(self, text='Sweet', variable=self.controller.app_data["popcorn"], value="Sweet").grid(column=2,row=1, sticky=W, padx=10)
def save_info():
pop_info=self.controller.app_data["popcorn"].get()
movie_info=self.controller.app_data["movie"].get()
week=["monday", "tuesday", "wednesday","thursday","friday","saturday","sunday"]
print("you like " + movie_info + " and you would like " + pop_info +" popcorn")
print("This is the body" + body)
test=len(week)
for i in range (0, test):
if self.controller.app_data[week[i]].get() == True:
print(week[i])
button_submit=ttk.Button(self, text="Submit", width=15,
command=save_info).grid(column=3, row= 10, padx=5)
app=Movies()
app.mainloop()
一种解决方案是像保存其他内容一样将小部件存储在控制器中。
例如:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.controller.app_data["user_message_entry"] = Text(self, height=10, width=60)
...
然后,要获取值,它类似于获取其他变量的方式:
body = self.controller.app_data['user_message_entry'].get("1.0", "end")
另一种访问它的方法是为您的控制器提供一个功能,该功能将 return 一个页面。然后,您可以使用 returned 页面访问它。
例如,首先在控制器中添加一个函数到return一个页面:
class Movies(tk.Tk):
...
def get_page(self, page_class):
return self.frames[page_class]
...
接下来,确保文本小部件是一个实例变量:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.user_message_entry' = tk.Text(self, height=10, width=60).grid(column=1, row= 3, padx=5)
...
最后,在控制器中使用该函数获取另一个页面,然后从那里获取文本小部件:
page = self.controller.get_page(PageOne)
body = page.textuser_message_entry.get("1.0", "end")
上面介绍了如何从多个地方访问文本小部件。但是,您还有另一个问题,因为您编写的代码试图在创建小部件几毫秒后从小部件中获取文本。您需要等到用户有机会在获取数据之前输入小部件。
例如,您需要将 body = page.textuser_message_entry.get("1.0", "end")
移动到 save_info
函数内部。