tkinter 中的多个条目小部件和一个按钮小部件
mutliple entry widgets and one button widget in tkinter
我正在尝试制作两个输入框和一个处理这两个条目的 'OK' 按钮:
我不明白 init() 函数或必须包含 'self' 的原因。
我想访问此 class 和 mainloop 之外的条目。条目应该是字符串类型。
from tkinter import *
root = Tk()
root.geometry("550x145+500+300")
class myDose:
def __init__(self):
l1 = Label(text="Enter the prescription dose to three (3) decimal places [cGy]").pack()
e1 = Entry(root)
e1.pack()
l2 = Label(text="Save new excel file as...").pack()
e2 = Entry(root)
e2.pack()
l3 = Label(text="click 'OK', and then close window.").pack()
b = Button(root, text="OK", command=submit)
b.pack()
def submit(self):
print(e1.get())
print(e2.get())
D = myDose()
root.mainloop()
#I want to access the entries, e1 and e2, outside the mainloop
print(D.e1)
print(D.e2)
您的方法存在根本性缺陷。 mainloop()
按照它说的去做:开始一个循环。在循环结束之前,它后面的行不会执行 - 也就是说,直到您的应用程序关闭。因为你已经有了一个 class 里面有 Tkinter 的东西,所以只需完成向 OO 方法的转变:
from tkinter import *
class myDose:
def __init__(self, root):
root.geometry("550x145+500+300")
self.l1 = Label(root, text="Enter the prescription dose to three (3) decimal places [cGy]")
self.l1.pack()
self.e1 = Entry(root)
self.e1.pack()
self.l2 = Label(root, text="Save new excel file as...")
self.l2.pack()
self.e2 = Entry(root)
self.e2.pack()
self.l3 = Label(root, text="click 'OK', and then close window.")
self.l3.pack()
self.b = Button(root, text="OK", command=self.submit)
self.b.pack()
def submit(self):
print(self.e1.get())
print(self.e2.get())
root = Tk()
D = myDose(root)
root.mainloop()
我建议在创建完整的 GUI 应用程序之前,更深入地了解对象和 classes 等基本概念的工作原理。
这是一个快速解决方法。
你的版本和TigerhawkT3的修改版本的问题是,当你关闭window时,Entry
小部件不再有效,所以你需要在关闭[=之前保存数据52=]。一种方法是将 Tkinter StringVar
s 附加到 Entry
小部件。 StringVar
中的值将在 window 关闭后可用。
import tkinter as tk
class myDose:
def __init__(self, root):
root.geometry("550x145+500+300")
l = tk.Label(root, text="Enter the prescription dose to three (3) decimal places [cGy]")
l.pack()
self.dosage = tk.StringVar()
e = tk.Entry(root, textvariable=self.dosage)
e.pack()
l = tk.Label(root, text="Save new excel file as...")
l.pack()
self.savename = tk.StringVar()
e = tk.Entry(root, textvariable=self.savename)
e.pack()
l = tk.Label(root, text="Enter the data and then close window.")
l.pack()
root.mainloop()
D = myDose(tk.Tk())
print(D.dosage.get())
print(D.savename.get())
请注意,我已经更改了 import
语句。 不
更干净
from tkinter import *
因为超过 100 个名称会使您的命名空间混乱,从而导致潜在的名称冲突。
__init__()
函数是myDose
class的一个方法。 class 的 __init__()
方法在创建 class 的实例时被调用。在您执行
时发生的代码中
D = myDose()
在我的版本中是执行此行的时间:
D = myDose(tk.Tk())
首先创建 Tkinter 根 window,然后传递给 myDose
;该根 window 然后可用于我的 __init__()
作为其 root
参数。
名称self
用于class 中以引用当前class 实例。在 class 之外,我们需要使用我们为实例分配的实际名称,在本例中为 D
.
问题是 mainloop
在根 window 被销毁之前不会退出。一旦根 window 被销毁,您将无法再访问根 window 中的小部件。但是,您可以访问对象的非小部件属性。
如果这就是您想要的 - 销毁 window 并访问小部件中的值 - 您需要在销毁 window.[=16 之前保存这些值=]
例如,在您的提交中,您可以像这样保存值:
def submit(self):
self.data = {"e1": self.e1.get(), "e2": self.e2.get()}
一旦 window 被销毁,您仍然拥有对应用程序对象的引用,因此您仍然可以访问 class 的非小部件属性:
...
D = myDose(root)
root.mainloop()
print D.data["e1"]
print D.data["e2"]
根据对原始问题的评论,您稍后在代码中提到您需要使用 askopenfilename
。如果是这种情况,您应该重新考虑 mainloop
之后 运行 代码的必要性。 Tkinter 设计为只创建一次根 window,并且程序在 mainloop
退出后立即退出。
您可以随心所欲地编写程序,但我认为如果您坚持正常的设计模式,那么长期 运行 您的代码将更易于维护和修改。将您的 "real" 代码移动到应用 class 的方法中,这将消除与被销毁的小部件相关的所有问题。
我正在尝试制作两个输入框和一个处理这两个条目的 'OK' 按钮: 我不明白 init() 函数或必须包含 'self' 的原因。 我想访问此 class 和 mainloop 之外的条目。条目应该是字符串类型。
from tkinter import *
root = Tk()
root.geometry("550x145+500+300")
class myDose:
def __init__(self):
l1 = Label(text="Enter the prescription dose to three (3) decimal places [cGy]").pack()
e1 = Entry(root)
e1.pack()
l2 = Label(text="Save new excel file as...").pack()
e2 = Entry(root)
e2.pack()
l3 = Label(text="click 'OK', and then close window.").pack()
b = Button(root, text="OK", command=submit)
b.pack()
def submit(self):
print(e1.get())
print(e2.get())
D = myDose()
root.mainloop()
#I want to access the entries, e1 and e2, outside the mainloop
print(D.e1)
print(D.e2)
您的方法存在根本性缺陷。 mainloop()
按照它说的去做:开始一个循环。在循环结束之前,它后面的行不会执行 - 也就是说,直到您的应用程序关闭。因为你已经有了一个 class 里面有 Tkinter 的东西,所以只需完成向 OO 方法的转变:
from tkinter import *
class myDose:
def __init__(self, root):
root.geometry("550x145+500+300")
self.l1 = Label(root, text="Enter the prescription dose to three (3) decimal places [cGy]")
self.l1.pack()
self.e1 = Entry(root)
self.e1.pack()
self.l2 = Label(root, text="Save new excel file as...")
self.l2.pack()
self.e2 = Entry(root)
self.e2.pack()
self.l3 = Label(root, text="click 'OK', and then close window.")
self.l3.pack()
self.b = Button(root, text="OK", command=self.submit)
self.b.pack()
def submit(self):
print(self.e1.get())
print(self.e2.get())
root = Tk()
D = myDose(root)
root.mainloop()
我建议在创建完整的 GUI 应用程序之前,更深入地了解对象和 classes 等基本概念的工作原理。
这是一个快速解决方法。
你的版本和TigerhawkT3的修改版本的问题是,当你关闭window时,Entry
小部件不再有效,所以你需要在关闭[=之前保存数据52=]。一种方法是将 Tkinter StringVar
s 附加到 Entry
小部件。 StringVar
中的值将在 window 关闭后可用。
import tkinter as tk
class myDose:
def __init__(self, root):
root.geometry("550x145+500+300")
l = tk.Label(root, text="Enter the prescription dose to three (3) decimal places [cGy]")
l.pack()
self.dosage = tk.StringVar()
e = tk.Entry(root, textvariable=self.dosage)
e.pack()
l = tk.Label(root, text="Save new excel file as...")
l.pack()
self.savename = tk.StringVar()
e = tk.Entry(root, textvariable=self.savename)
e.pack()
l = tk.Label(root, text="Enter the data and then close window.")
l.pack()
root.mainloop()
D = myDose(tk.Tk())
print(D.dosage.get())
print(D.savename.get())
请注意,我已经更改了 import
语句。 不
from tkinter import *
因为超过 100 个名称会使您的命名空间混乱,从而导致潜在的名称冲突。
__init__()
函数是myDose
class的一个方法。 class 的 __init__()
方法在创建 class 的实例时被调用。在您执行
D = myDose()
在我的版本中是执行此行的时间:
D = myDose(tk.Tk())
首先创建 Tkinter 根 window,然后传递给 myDose
;该根 window 然后可用于我的 __init__()
作为其 root
参数。
名称self
用于class 中以引用当前class 实例。在 class 之外,我们需要使用我们为实例分配的实际名称,在本例中为 D
.
问题是 mainloop
在根 window 被销毁之前不会退出。一旦根 window 被销毁,您将无法再访问根 window 中的小部件。但是,您可以访问对象的非小部件属性。
如果这就是您想要的 - 销毁 window 并访问小部件中的值 - 您需要在销毁 window.[=16 之前保存这些值=]
例如,在您的提交中,您可以像这样保存值:
def submit(self):
self.data = {"e1": self.e1.get(), "e2": self.e2.get()}
一旦 window 被销毁,您仍然拥有对应用程序对象的引用,因此您仍然可以访问 class 的非小部件属性:
...
D = myDose(root)
root.mainloop()
print D.data["e1"]
print D.data["e2"]
根据对原始问题的评论,您稍后在代码中提到您需要使用 askopenfilename
。如果是这种情况,您应该重新考虑 mainloop
之后 运行 代码的必要性。 Tkinter 设计为只创建一次根 window,并且程序在 mainloop
退出后立即退出。
您可以随心所欲地编写程序,但我认为如果您坚持正常的设计模式,那么长期 运行 您的代码将更易于维护和修改。将您的 "real" 代码移动到应用 class 的方法中,这将消除与被销毁的小部件相关的所有问题。