【问题标题】:Can't insert a user input value because "str object has no attribute get" in tkinter无法插入用户输入值,因为 tkinter 中的“str object has no attribute get”
【发布时间】:2016-02-08 01:49:44
【问题描述】:

其他几个人也问过类似的问题,但我认为它们不一定适用于我的情况。我正在编写一个程序,该程序最终将接受用户输入,检查以确保它们正确,然后将其全部保存到文件中。目前,我将所有用户输入传递到 tkinter 中的文本框,以便我可以保存该文本框中的任何内容。我正在使用 for 循环遍历我拥有的 7 个用户输入字段,然后将它们插入到文本框中。

def submit(self):
    """ submits user data up to input data section of GUI and checks USL vs LSL"""
    e6 = IntVar(self.e6)
    e7 = IntVar(self.e7)

    if e6 > e7:
        message = "Limits are good"
    else:
        message = "USL can't be less than LSL, please re-enter USL and LSL"

    self.checklimits.delete(0.0, END)
    self.checklimits.insert(0.0, message)


    x = 1
    for x in range (1, 8):
       xname = "self.e" + str(x)
       entry = xname.get()
       if entry:
            self.checktext.insert(END, entry + "\n")
       x = x+1

我想在 for 循环中获取 x 值并最终得到类似“self.e#.get()”的内容,因为这就是我定义用户条目的方式,请参见下面的示例:

 def create_widgets(self):
    """create widgets for user inputted data"""      
    # creates a text widget next to the entries that displays what the user has input
    Label(self, text = "Do these values you entered seem correct?").grid(row = 0, column = 4, sticky = W, padx = 5, pady = 5)
    self.checktext = Text(self, width =15, height = 42, wrap = WORD)
    self.checktext.grid(row = 1, rowspan = 10, column = 4, sticky = W, padx =5, pady =5)

    # get name
    Label(self, text = "First Name:").grid(row = 0, column = 0, sticky = W, padx=5, pady=5)
    self.e1 = Entry(self)
    self.e1.grid(row = 0, column = 1)       
    Label(self, text = "Last Name:").grid(row = 1, column = 0, sticky = W, padx=5, pady=5)
    self.e2 = Entry(self)
    self.e2.grid(row = 1, column = 1)

不过现在,python 并没有将该条目识别为一个条目,而是对我说“'str' object has no attribute 'get'”

所以,一是为什么我不能“获取”一个字符串值,二是如何让 python 识别我之前定义的条目?这是我的整个上下文代码

from Tkinter import *

class Application(Frame):
""" A SPC program that takes user input and saves the file """
def __init__(self,master):
    """ initializes the frame """
    Frame.__init__(self,master)
    self.grid()
    self.create_widgets()     

def create_widgets(self):
    """create widgets for user inputted data"""      
    # creates a text widget next to the entries that displays what the user  has input
    Label(self, text = "Do these values you entered seem correct?").grid(row = 0, column = 4, sticky = W, padx = 5, pady = 5)
    self.checktext = Text(self, width =15, height = 42, wrap = WORD)
    self.checktext.grid(row = 1, rowspan = 10, column = 4, sticky = W, padx =5, pady =5)

    # get name
    Label(self, text = "First Name:").grid(row = 0, column = 0, sticky = W, padx=5, pady=5)
    self.e1 = Entry(self)
    self.e1.grid(row = 0, column = 1)       
    Label(self, text = "Last Name:").grid(row = 1, column = 0, sticky = W, padx=5, pady=5)
    self.e2 = Entry(self)
    self.e2.grid(row = 1, column = 1)

    # get work order
    Label(self, text = "Work Order Number:").grid(row = 2, column = 0, sticky = W, padx=5, pady=5)
    self.e3 = Entry(self)
    self.e3.grid(row = 2, column = 1)

    # get todays date
    Label(self, text = "Todays Date:").grid(row = 3, column = 0, sticky = W, padx=5, pady=5)
    self.e4 = Entry(self)
    self.e4.grid(row = 3, column = 1)

    # get bubble number
    Label(self, text = "Bubble Number:").grid(row = 4, column = 0, sticky = W, padx=5, pady=5)
    self.e5 = Entry(self)
    self.e5.grid(row = 4, column = 1)

    # get USL and LSL
    Label(self, text = "USL:").grid(row = 5, column = 0, sticky = W, padx=5, pady=5)        
    self.e6 = Entry(self)
    self.e6.grid(row = 5, column = 1)    
    Label(self, text = "LSL:").grid(row = 6, column = 0, sticky = W, padx=5, pady=5)       
    self.e7 = Entry(self)
    self.e7.grid(row = 6, column = 1)                       

    """# button to check USL is higher than LSL
    self.button7 = Button(self)
    self.button7["text"] = "Check Limits"
    self.button7["command"] = self.check_limits
    self.button7.grid(row = 6, column = 2, sticky = W, padx=5, pady=5)"""

    # button to submit user entered values up to the input data values portion of the gui
    self.button6 = Button(self)
    self.button6["text"] = "Submit"
    self.button6["command"] = self.submit
    self.button6.grid(row = 5, column = 2, sticky = W, padx=5, pady=5)

    # creates a spot to dictate whether USL and LSL are correct
    self.checklimits = Text(self, width = 20, height = 2, wrap = WORD)
    self.checklimits.grid(row = 6, column = 3, sticky = W, padx = 5)

    """ #adds a scroll bar to the data input text box
    scrollbar = Scrollbar(self)
    scrollbar.pack(side=RIGHT, fill=Y) """

    # get User Input Data values
    Label(self, text = "Enter Results:").grid(row = 7, column = 0, sticky = W, padx=5, pady=5)        
    self.e8 = Text(self, width = 15, height = 30)
    self.e8.grid(row = 7, column = 1)     

    """ def check_limits(self):
    checks to see if the USL is greater than the LSL 

    e6 = IntVar(self.e6)
    e7 = IntVar(self.e7)

    if e6 > e7:
        message = "Limits are good"
    else:
        message = "USL can't be less than LSL, please re-enter USL and LSL"

    self.checklimits.delete(0.0, END)
    self.checklimits.insert(0.0, message)"""

def submit(self):
    """ submits user data up to input data section of GUI and checks USL vs LSL"""
    e6 = IntVar(self.e6)
    e7 = IntVar(self.e7)

    if e6 > e7:
        message = "Limits are good"
    else:
        message = "USL can't be less than LSL, please re-enter USL and LSL"

    self.checklimits.delete(0.0, END)
    self.checklimits.insert(0.0, message)


    x = 1
    for x in range (1, 8):
       xname = "self.e" + str(x)
       entry = xname.get()
       if entry:
            self.checktext.insert(END, entry + "\n")
       x = x+1                              

root = Tk()
root.title("SPC Input Program")
root.geometry("700x750")

app = Application(root)

root.mainloop()

【问题讨论】:

  • 不要使用这样的名称创建变量。请改用列表或字典。
  • 使用eval(xname) 而不是xname.get() 尽管凯文的建议更好

标签: python python-2.7 tkinter tk


【解决方案1】:

您似乎假设e6 = IntVar(self.e6) 正在获取条目小部件的值并将其转换为int。那不是它正在做的事情。它正在创建一个名为e6 的新变量,该变量初始化为零,并将self.e6 作为“主”。

如果您想从条目小部件中获取值并将其转换为整数,请在条目小部件上使用get 方法。

e6 = int(self.e6.get())
e7 = int(self.e7.get())

导致“str object has no method get”的问题是这段代码:

xname = "self.e" + str(x)
entry = xname.get()

这是一种糟糕的编码方式。如您所见,它不起作用。您可以使用技巧使其工作,但一个好的经验法则是永远不要尝试像这样动态创建变量。

如果您想循环访问条目小部件,请将它们放在列表或元组中。例如:

for widget in (self.e1, self.e2, self.e3, self.e4,
              self.e5, self.e6, self.e7, self.e8):
    entry = widget.get()
   if entry:
       self.checktext.insert(END, entry + "\n")
   ...

【讨论】:

  • 当您使用它时,将self.e# 重构为self.e[#]。然后你可以直接循环self.e。
  • 所以@Bryan Oakley 提交的内容有效,但我喜欢将条目存储到数组中的想法。那么我该怎么做呢,@Kevin?我试过这样做:for x in self.e: entry = x.get() if entry: self.checktext.delete(0.0, END) self.checktext.insert(END, entry + "\n") 但只通过最后一个条目,而不是全部
  • @jvaille:无论您在哪里设置self.e# 变量(在__init__() 函数中?),您都需要将其更改为创建列表或字典并填充它。
  • @Kevin: 这不是我用这行代码self.entry_list = [None]*7 做的吗?我把它放在代码顶部的__init__() 函数中
  • @jvaille:这会创建一个名为self.entry_list 的列表。如果您想对名为self.e 的列表进行操作,则需要先创建它。另外,请记住 Python 列表从零开始计数。如果您需要从 1 开始数,则需要一本字典。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 2021-06-24
  • 2017-05-10
  • 1970-01-01
  • 2020-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多