我正在尝试制作两个输入框和一个' OK'处理两个条目的按钮: 我不理解 init ()函数或原因' self'必须包括这样做。 我想访问这个类和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)
答案 0 :(得分:1)
问题是mainloop
在根窗口被销毁之前不会退出。一旦根窗口被销毁,您就无法再访问根窗口内的小部件。但是,您可以访问该对象的非窗口小部件属性。
如果这是您想要的 - 破坏窗口并访问窗口小部件中的值 - 您需要在销毁窗口之前保存这些值。
例如,在您的提交中,您可以保存以下值:
def submit(self):
self.data = {"e1": self.e1.get(), "e2": self.e2.get()}
一旦窗口被销毁,您仍然可以引用应用程序对象,因此您仍然可以访问该类的非窗口小部件属性:
...
D = myDose(root)
root.mainloop()
print D.data["e1"]
print D.data["e2"]
根据对原始问题的评论,您提到稍后在您的代码中,您需要使用askopenfilename
。如果是这种情况,您应该重新考虑在mainloop
之后运行代码的必要性。 Tkinter设计为只创建一次根窗口,并且程序在mainloop
退出后立即退出。
您可以随意编写程序,但我认为如果您坚持正常的设计模式,您的代码将更容易维护和修改。移动你的真实"将代码编写到app类的方法中,这将消除与小部件被销毁相关的所有问题。
答案 1 :(得分:0)
您的方法存在根本缺陷。 mainloop()
做了它所说的:开始一个循环。在该循环结束之前,不会执行其后面的行 - 这意味着,直到您的应用程序关闭。既然你已经有了一个带有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应用程序之前,更全面地了解对象和类等基本概念的工作原理。
答案 2 :(得分:0)
这是一个快速解决方案。
您的版本和TigerhawkT3修改版本的问题在于,当您关闭窗口时,Entry
窗口小部件不再有效,因此您需要在关闭窗口之前保存数据。一种方法是将Tkinter StringVar
附加到Entry
小部件。窗口关闭后,StringVar
s中的值将可用。
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
类的方法。创建该类的实例时,将调用类的__init__()
方法。在您执行的代码中
D = myDose()
在我的版本中执行此行的时间:
D = myDose(tk.Tk())
首先创建Tkinter根窗口,然后传递给myDose
;然后,根窗口可以作为__init__()
参数用于我的root
。
在类中使用名称self
来引用当前的类实例。在课外,我们需要使用我们为实例分配的实际名称,在本例中为D
。