Python tkinter中的多输入小部件和一键小部件

Python tkinter中的多输入小部件和一键小部件,python,class,tkinter,init,self,Python,Class,Tkinter,Init,Self,我正在尝试创建两个输入框和一个“确定”按钮来处理这两个输入: 我不理解init的函数,也不理解为什么在执行此操作时必须包含“self”。 我想访问这个类和mainloop之外的条目。条目应为字符串类型 from tkinter import * root = Tk() root.geometry("550x145+500+300") class myDose: def __init__(self): l1 = Label(text="Enter the prescri

我正在尝试创建两个输入框和一个“确定”按钮来处理这两个输入: 我不理解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)

你的方法根本上是有缺陷的
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应用程序之前,更彻底地了解对象和类等基本概念是如何工作的。

这里有一个快速解决方案

您的版本和TigerhawkT3的修改版本的问题在于,当您关闭窗口时,
条目
小部件不再有效,因此您需要在关闭窗口之前保存数据。一种方法是将Tkinter
StringVar
s附加到
条目
小部件。关闭窗口后,
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
语句。不这样做要干净得多

因为这会使名称空间中的名称超过100个,从而导致潜在的名称冲突


\uuu init\uuu()
函数是
myDose
类的一种方法。创建类的实例时,将调用该类的
\uuuu init\uuu()
方法。在您的代码中,当您

D = myDose()
在我的版本中,执行这一行时:

D = myDose(tk.Tk())
它首先创建Tkinter根窗口,然后将其传递给
myDose
;然后,该根窗口作为其
root
参数可供my
\uuuu init\uuu()
使用


类内部使用名称
self
来引用当前类实例。在类之外,我们需要使用分配给实例的实际名称,在本例中是
D

问题是
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类的方法中,这将消除与被销毁的小部件相关的所有问题。

您所说的OO方法是什么意思?我需要访问“root.mainloop”行下面的条目。我的其他代码取决于在root.mainloop下面获得@tigerhawkt3go print(D.e1)这些值。mainloop给了我一些随机值,如。6745325@Michael在TigerhawkT3版本的脚本中,您是否尝试在
root.mainloop()
之后执行
print(D.e1.get())
,它不是这样的:_tkinter.TclError:invalid command name“.4744112”意思是,直到你的应用程序关闭为止。mainloop一直运行,直到根寡妇被销毁。应用程序本身可以仍然处于活动状态(或“打开”,或“运行”,无论您喜欢什么术语)。此外,窗口小部件也将被销毁,
D
指向的对象将仍然存在。你知道吗?或者您正在询问如何在
mainloop
之后运行代码,但窗口仍然可见?我已经编写了此类以上的函数。它们依赖于这个e1变量。这就是为什么我想得到用户的条目号1。在这个类下面,在我的程序中,我有一个类似main()函数的代码(也就是说,它是我的代码开始运行的地方),这取决于e2。它们是否依赖于e1小部件,或者输入到小部件中的值?@BryanOakley所以基本上我只想在我的代码中使用这些输入值,而不是输入到小部件中的字符串@BryanOakley@Michael-请记住,了解您的意思并不等于同意您以合理的方式构建程序。我建议研究Tkinter应用程序——特别是如何使用此类应用程序访问数据模型——以便正确编写程序。这将使以后使用代码变得更加容易。@Michael-这是真的,但如果“它有效”仍然是您唯一的标准,那么以后使用此代码将变得更加困难。仔细考虑你是否真的想放弃Python强调可读的代码和规范的方法。@ TiGHAKKT3:在看到对原始问题的新的评论后,你是正确的,这是一个糟糕的设计。我更新了我的答案,希望能解决这个问题。既然我们知道OP将不仅仅在启动时使用Tkinter,我们应该鼓励更好的总体架构。当你说“早期版本的问题”时,你在说什么“早期版本”?答案的顺序可能与你写答案的顺序不同。你呢
...
D = myDose(root)
root.mainloop()

print D.data["e1"]
print D.data["e2"]