首页 > 解决方案 > 在用户输入后将条目的值保存在重复函数中

问题描述

嗨,我的名字是克里斯,我的代码有点到处都是,这也是我第一次提问。所以我的问题是我有一个按钮,按下时每次按下都会运行一个函数,这个函数在一个花药旁边创建 3 个条目,用户应该在每个输入框中输入适当的信息,我的问题是我添加按下按钮时假设从每个现有条目行中提取值并保存它,我想稍后用它来做方程式。我的问题是,由于我正在重复条目,它们每次都不是唯一的,而是一个克隆,所以我似乎无法告诉程序找到每个条目,因为它们是彼此的克隆,或者至少我是这么认为的。

我尝试了许多不同的保存值的方法,所以这里是我尝试的每种方法:

这是我的代码的一部分,没有我尝试保存值的代码:

import tkinter as tk
Window4 = tk.Tk()
Window4.title("Budget Program")
Window4.geometry("700x400")
windowWidth = Window4.winfo_reqwidth()
windowHeight = Window4.winfo_reqheight()
positionRight = int(Window4.winfo_screenwidth() / 2 - windowWidth / 2)
positionDown = int(Window4.winfo_screenheight() / 2 - windowHeight / 2)
Window4.geometry("+{}+{}".format(positionRight, positionDown))

class App(object):
    def new_row(self):

        v = tk.StringVar()

        entry_Box = tk.Entry(Window4, width=15, textvariable=v)
        name = entry_Box.insert(0, "Name of income")

        entry_Box2 = tk.Entry(Window4, width=8)
        amount = entry_Box2.insert(0, "Amount")

        rate = OptionList = [
        "Hourly",
        "Daily",
        "Weekly",
        "Monthly"
        ]
        variable = tk.StringVar(Window4)
        variable.set(OptionList[0])

        opt = tk.OptionMenu(Window4, variable, *OptionList)
        opt.config(width=5, font=('Helvetica', 6))

        blank = tk.Label(Window4, text="  ")

        # Put widgets in grid
        self.num_rows += 1
        self.num_rows2 += 1
        self.num_rows3 += 1
        self.num_rows4 += 1

        opt.grid(column=3, row=self.num_rows3)
        opt.bind("<Button-1>")

        entry_Box.grid(column=0, row=self.num_rows)
        def some_callback(event):
            entry_Box.delete(0, "end")
            return None
        entry_Box.bind("<Button-1>", some_callback)

        entry_Box2.grid(column=1, row=self.num_rows2)
        def some_callback(event):
            entry_Box2.delete(0, "end")
            return None
        entry_Box2.bind("<Button-1>", some_callback)

        blank.grid(column=6, row=self.num_rows4, padx=160)

    def __init__(self):
        self.num_rows = 1
        self.num_rows2 = 1
        self.num_rows3 = 1
        self.num_rows4 = 1
        createRow_button = tk.Button(
                Window4, text='Add income row', command=self.new_row)
        createRow_button.place(x=240, y=0)
app = App()
Window4.mainloop()

我首先尝试简单地使用 .get() 函数:

import tkinter as tk
Window4 = tk.Tk()
Window4.title("Budget Program")
Window4.geometry("700x400")
windowWidth = Window4.winfo_reqwidth()
windowHeight = Window4.winfo_reqheight()
positionRight = int(Window4.winfo_screenwidth() / 2 - windowWidth / 2)
positionDown = int(Window4.winfo_screenheight() / 2 - windowHeight / 2)
Window4.geometry("+{}+{}".format(positionRight, positionDown))
class App(object):
    def new_row(self):
        new_entry = tk.Entry(Window4, width=15)
        name = new_entry.insert(0, "Name of income")

        new_entry2 = tk.Entry(Window4, width=8)
        amount = new_entry2.insert(0, "Amount")

        rate = OptionList = [
        "Hourly",
        "Daily",
        "Weekly",
        "Monthly"
        ]
        variable = tk.StringVar(Window4)
        variable.set(OptionList[0])

        opt = tk.OptionMenu(Window4, variable, *OptionList)
        opt.config(width=5, font=('Helvetica', 6))

        blank = tk.Label(Window4, text="  ")

        # Put widgets in grid
        self.num_rows += 1
        self.num_rows2 += 1
        self.num_rows3 += 1
        self.num_rows4 += 1
        opt.grid(column=3, row=self.num_rows3)
        opt.bind("<Button-1>")

        new_entry.grid(column=0, row=self.num_rows)
        def some_callback(event):
            new_entry.delete(0, "end")
            return None
        new_entry.bind("<Button-1>", some_callback)

        new_entry2.grid(column=1, row=self.num_rows2)
        def some_callback(event):
            new_entry2.delete(0, "end")
            return None
        new_entry2.bind("<Button-1>", some_callback)

        blank.grid(column=6, row=self.num_rows4, padx=160)

        return name
        return amount
        return rate

    def __init__(self):
        self.num_rows = 1
        self.num_rows2 = 1
        self.num_rows3 = 1
        self.num_rows4 = 1
        createRow_button = tk.Button(
                Window4, text='Add income row', command=self.new_row)
        createRow_button.place(x=240, y=0)
app = App()

def budget(name, amount, rate):

    nameincome = name.get()
    print(nameincome)

    amountincome = amount.get()
    print(amountincome)

    rateincome = rate.get()
    print(rateincome)

Submitlabel = tk.Label(Window4, text="When you are done click below to work out your budget.", )
Submitlabel.place(x=240, y=40)

Submitbtn = tk.Button(Window4, text="Submit", command=lambda: budget(name, amount, rate))
Submitbtn.place(x=365, y=90)

Window4.mainloop()

但是得到了错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/Meyerc2/.PyCharmEdu2019.3/config/scratches/scratch_5.py", line 82, in <lambda>
    Submitbtn = tk.Button(Window4, text="Submit", command=lambda: budget(name, amount, rate))
NameError: name 'name' is not defined

然后我尝试直接从条目中获取值,而不是变量名:

import tkinter as tk
Window4 = tk.Tk()
Window4.title("Budget Program")
Window4.geometry("700x400")
windowWidth = Window4.winfo_reqwidth()
windowHeight = Window4.winfo_reqheight()
positionRight = int(Window4.winfo_screenwidth() / 2 - windowWidth / 2)
positionDown = int(Window4.winfo_screenheight() / 2 - windowHeight / 2)
Window4.geometry("+{}+{}".format(positionRight, positionDown))


class App(object):
    def new_row(self):
        new_entry = tk.Entry(Window4, width=15)
        name = new_entry.insert(0, "Name of income")

        new_entry2 = tk.Entry(Window4, width=8)
        amount = new_entry2.insert(0, "Amount")

        rate = OptionList = [
            "Hourly",
            "Daily",
            "Weekly",
            "Monthly"
        ]
        variable = tk.StringVar(Window4)
        variable.set(OptionList[0])
        opt = tk.OptionMenu(Window4, variable, *OptionList)
        opt.config(width=5, font=('Helvetica', 6))

        blank = tk.Label(Window4, text="  ")

        # Put widgets in grid
        self.num_rows += 1
        self.num_rows2 += 1
        self.num_rows3 += 1
        self.num_rows4 += 1
        opt.grid(column=3, row=self.num_rows3)
        opt.bind("<Button-1>")

        new_entry.grid(column=0, row=self.num_rows)

        def some_callback(event):
            new_entry.delete(0, "end")
            return None
        new_entry.bind("<Button-1>", some_callback)

        new_entry2.grid(column=1, row=self.num_rows2)

        def some_callback(event):
            new_entry2.delete(0, "end")
            return None
        new_entry2.bind("<Button-1>", some_callback)

        blank.grid(column=6, row=self.num_rows4, padx=160)

        return new_entry, new_entry2, variable

    def __init__(self):
        self.num_rows = 1
        self.num_rows2 = 1
        self.num_rows3 = 1
        self.num_rows4 = 1
        createRow_button = tk.Button(
            Window4, text='Add income row', command=self.new_row)
        assert isinstance(createRow_button, object)
        createRow_button.place(x=240, y=0)


app = App()


def budget(new_entry, new_entry2, variable):
    nameincome = new_entry.get()
    print(nameincome)

    amountincome = new_entry2.get()
    print(amountincome)

    rateincome = variable.get()
    print(rateincome)


Submitlabel = tk.Label(Window4, text="When you are done click below to work out your budget.", )
Submitlabel.place(x=240, y=40)

Submitbtn = tk.Button(Window4, text="Submit", command=lambda: budget(new_entry, new_entry2, variable))
Submitbtn.place(x=365, y=90)

Window4.mainloop()

但是得到了错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/Meyerc2/.PyCharmEdu2019.3/config/scratches/scratch_5.py", line 87, in <lambda>
    Submitbtn = tk.Button(Window4, text="Submit", command=lambda: budget(new_entry, new_entry2, variable))
NameError: name 'new_entry' is not defined

接下来我尝试将其保存到列表中:

import tkinter as tk

Window4 = tk.Tk()
Window4.title("Budget Program")
Window4.geometry("700x400")
windowWidth = Window4.winfo_reqwidth()
windowHeight = Window4.winfo_reqheight()
positionRight = int(Window4.winfo_screenwidth() / 2 - windowWidth / 2)
positionDown = int(Window4.winfo_screenheight() / 2 - windowHeight / 2)
Window4.geometry("+{}+{}".format(positionRight, positionDown))


class App(object):
    def new_row(self):
        v = tk.StringVar()
        new_entry = tk.Entry(Window4, width=15, textvariable=v)
        name = new_entry.insert(0, "Name of income")

        mylist = []

        new_entry2 = tk.Entry(Window4, width=8)
        amount = new_entry2.insert(0, "Amount")

        rate = OptionList = [
            "Hourly",
            "Daily",
            "Weekly",
            "Monthly"
        ]
        variable = tk.StringVar(Window4)
        variable.set(OptionList[0])
        opt = tk.OptionMenu(Window4, variable, *OptionList)
        opt.config(width=5, font=('Helvetica', 6))

        blank = tk.Label(Window4, text="  ")

        # Put widgets in grid
        self.num_rows += 1
        self.num_rows2 += 1
        self.num_rows3 += 1
        self.num_rows4 += 1
        opt.grid(column=3, row=self.num_rows3)
        opt.bind("<Button-1>")

        new_entry.grid(column=0, row=self.num_rows)

        def some_callback(event):
            new_entry.delete(0, "end")
            return None

        new_entry.bind("<Button-1>", some_callback)

        new_entry2.grid(column=1, row=self.num_rows2)

        def some_callback(event):
            new_entry2.delete(0, "end")
            return None

        new_entry2.bind("<Button-1>", some_callback)

        blank.grid(column=6, row=self.num_rows4, padx=160)

        mylist.append(name)
        mylist.append(amount)
        mylist.append(rate)
        return new_entry, new_entry2, rate

    def __init__(self):
        self.num_rows = 1
        self.num_rows2 = 1
        self.num_rows3 = 1
        self.num_rows4 = 1
        createRow_button = tk.Button(
            Window4, text='Add income row', command=self.new_row)
        createRow_button.place(x=240, y=0)


app = App()

new_entry2 = ''
rate = ''


def income():
    nameincome = App.new_row().find(App.new_row())
    amountincome = App.new_entry2.get()
    rateincome = App.rate

    print(nameincome, amountincome, rateincome)


btn = tk.Button(Window4, text="go", command=lambda: income())
btn.place(x=270, y=0)

Submitlabel = tk.Label(Window4, text="When you are done click below to work out your budget.", )
Submitlabel.place(x=240, y=40)

Window4.mainloop()

但是得到了错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/Meyerc2/.PyCharmEdu2019.3/config/scratches/scratch_5.py", line 92, in <lambda>
    btn = tk.Button(Window4, text="go", command=lambda: income())
  File "C:/Users/Meyerc2/.PyCharmEdu2019.3/config/scratches/scratch_5.py", line 85, in income
    nameincome = App.new_row().find(App.new_row())
TypeError: new_row() missing 1 required positional argument: 'self'

接下来我尝试使用 App() 函数从类中获取值,以便我可以在函数中使用它:

import tkinter as tk

Window4 = tk.Tk()
Window4.title("Budget Program")
Window4.geometry("700x400")
windowWidth = Window4.winfo_reqwidth()
windowHeight = Window4.winfo_reqheight()
positionRight = int(Window4.winfo_screenwidth() / 2 - windowWidth / 2)
positionDown = int(Window4.winfo_screenheight() / 2 - windowHeight / 2)
Window4.geometry("+{}+{}".format(positionRight, positionDown))


class App(object):
    def new_row(self):
        v = tk.StringVar()
        new_entry = tk.Entry(Window4, width=15, textvariable=v)
        name = new_entry.insert(0, "Name of income")

        mylist = []

        new_entry2 = tk.Entry(Window4, width=8)
        amount = new_entry2.insert(0, "Amount")

        rate = OptionList = [
            "Hourly",
            "Daily",
            "Weekly",
            "Monthly"
        ]
        variable = tk.StringVar(Window4)
        variable.set(OptionList[0])
        opt = tk.OptionMenu(Window4, variable, *OptionList)
        opt.config(width=5, font=('Helvetica', 6))

        blank = tk.Label(Window4, text="  ")

        # Put widgets in grid
        self.num_rows += 1
        self.num_rows2 += 1
        self.num_rows3 += 1
        self.num_rows4 += 1
        opt.grid(column=3, row=self.num_rows3)
        opt.bind("<Button-1>")

        new_entry.grid(column=0, row=self.num_rows)

        def some_callback(event):
            new_entry.delete(0, "end")
            return None

        new_entry.bind("<Button-1>", some_callback)

        new_entry2.grid(column=1, row=self.num_rows2)

        def some_callback(event):
            new_entry2.delete(0, "end")
            return None

        new_entry2.bind("<Button-1>", some_callback)

        blank.grid(column=6, row=self.num_rows4, padx=160)

        mylist.append(name)
        mylist.append(amount)
        mylist.append(rate)
        return new_entry, new_entry2, rate

    def __init__(self):
        self.num_rows = 1
        self.num_rows2 = 1
        self.num_rows3 = 1
        self.num_rows4 = 1
        createRow_button = tk.Button(
            Window4, text='Add income row', command=self.new_row)
        createRow_button.place(x=240, y=0)

app = App()

new_entry2 = ''
rate = ''
def income():

    nameincome = App.new_row().find(App.new_row())
    amountincome = App.new_entry2.get()
    rateincome = App.rate

    print(nameincome, amountincome, rateincome)

btn = tk.Button(Window4, text="go", command=lambda: income())
btn.place(x=270, y=0)


Submitlabel = tk.Label(Window4, text="When you are done click below to work out your budget.", )
Submitlabel.place(x=240, y=40)

Window4.mainloop()

并得到错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/Meyerc2/.PyCharmEdu2019.3/config/scratches/scratch_5.py", line 89, in <lambda>
    btn = tk.Button(Window4, text="go", command=lambda: income())
  File "C:/Users/Meyerc2/.PyCharmEdu2019.3/config/scratches/scratch_5.py", line 83, in income
    nameincome = App.new_row().find(App.new_row())
TypeError: new_row() missing 1 required positional argument: 'self'

现在我正在尝试使用增量为每个条目创建一个唯一的名称,以便能够保存它:

    import tkinter as tk
Window4 = tk.Tk()
Window4.title("Budget Program")
Window4.geometry("700x400")
windowWidth = Window4.winfo_reqwidth()
windowHeight = Window4.winfo_reqheight()
positionRight = int(Window4.winfo_screenwidth() / 2 - windowWidth / 2)
positionDown = int(Window4.winfo_screenheight() / 2 - windowHeight / 2)
Window4.geometry("+{}+{}".format(positionRight, positionDown))


class App(object):
    def new_row(self):

        Unique_Val = 0
        Unique_Val_A = 0

        v = tk.StringVar()
        entry_Box = "new_entry{}".format(Unique_Val)
        entry_Box = tk.Entry(Window4, width=15, textvariable=v)
        name = entry_Box.insert(0, "Name of income")
        Unique_Val += 1

        entry_Box2 = "new_entry2{}".format(Unique_Val_A)
        entry_Box2 = tk.Entry(Window4, width=8)
        amount = entry_Box2.insert(0, "Amount")
        Unique_Val_A += 1

        rate = OptionList = [
        "Hourly",
        "Daily",
        "Weekly",
        "Monthly"
        ]
        variable = tk.StringVar(Window4)
        variable.set(OptionList[0])

        opt = tk.OptionMenu(Window4, variable, *OptionList)
        opt.config(width=5, font=('Helvetica', 6))

        blank = tk.Label(Window4, text="  ")

        # Put widgets in grid
        self.num_rows += 1
        self.num_rows2 += 1
        self.num_rows3 += 1
        self.num_rows4 += 1

        opt.grid(column=3, row=self.num_rows3)
        opt.bind("<Button-1>")

        entry_Box.grid(column=0, row=self.num_rows)
        def some_callback(event):
            entry_Box.delete(0, "end")
            return None
        entry_Box.bind("<Button-1>", some_callback)

        entry_Box2.grid(column=1, row=self.num_rows2)
        def some_callback(event):
            entry_Box2.delete(0, "end")
            return None
        entry_Box2.bind("<Button-1>", some_callback)

        blank.grid(column=6, row=self.num_rows4, padx=160)

        return entry_Box, entry_Box2, rate

    def save(self):
        name1 = self.entry_Box.get()
        amount1 = self.entry_Box2.get()

        mylist = []
        mylist.append(name1)
        mylist.append(amount1)

        print(mylist)


    def __init__(self):
        self.num_rows = 1
        self.num_rows2 = 1
        self.num_rows3 = 1
        self.num_rows4 = 1
        createRow_button = tk.Button(
                Window4, text='Add income row', command=self.new_row)
        createRow_button.place(x=240, y=0)
        savebtn = tk.Button(Window4, text="save", command=self.save)
        savebtn.place(x=240, y=50)

app = App()

Window4.mainloop()

但我得到错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/Meyerc2/.PyCharmEdu2019.3/config/scratches/scratch_1.py", line 69, in save
    name1 = self.entry_Box.get()
AttributeError: 'App' object has no attribute 'entry_Box'

如果您需要任何其他信息,我很乐意提供帮助,如果需要,我也有一个 GitHub,如果需要,我也可以提供我的整个代码,我正在使用 pycharm。

标签: pythontkinter

解决方案


我添加这个只是为了让您了解要做什么或做什么,这只是如何进行的方法之一。

基本上,只需在调用中创建两个空列表,__init__然后将这些条目小部件附加到之前创建的列表中,例如:

def __init__(self):
    .....#same bunch of code
    self.lst1 = []
    self.lst2 = []

然后在你的new_row()方法结束时,说:

def new_row():
    ....#same bunch of codes

    self.lst1.append(entry_Box)
    self.lst2.append(entry_Box2)

现在以这种方式访问​​条目小部件,例如print(lst1[0].get()). 这将返回第一列第一个框中的内容。print(lst2[0].get())将返回第二列第一个框中的内容,这样,您将获得矩阵类型排列的模式,并且可以轻松获得这样的值。

虽然我建议删除与条目小部件的绑定,因为它们稍后会给您带来问题,但如果您正在寻找使用 tkinter 条目小部件创建占位符,请查看此处。不是完美的课程,但仍然可以完成工作。

还要记住它们是无用的name,所以使用它们没有意义。amountNone


推荐阅读