如何将循环函数创建的值插入到也使用循环函数自动创建的 tkinter 文本框

How to insert values created by a loop function to tkinter text boxes which are also created automatically with a loop function

您好,我正在尝试编写一个代码来计算分期付款的净现值。代码运行完美,直到我无法将计算值单独插入 tkinter 文本框。

例如,代码询问年利率,输入可以是 15。房子的标价可以是 1000000,首付可以是 0.2,即标价的 %20。而我们可以输入12作为分期付款的次数。

预付款将通过 1000000 乘以 0.2 得出 200000。执行将插入到第一个 tkinter 文本框。但是当对分期付款的净现值进行计算时,它们都出现在最后一个 tkinter 文本框中,而不是单独出现。

这是代码;

# This program is to create a payment schedule for the customers and check whether
# the payment plan is suitable for the seller in terms of net present value.

from tkinter import *

window=Tk()
    
# This part asks the number of installments and creates the desired amount of text boxes.
def create():
    for y in range(number_of_installments.get()):
        t11 = Label(window,text= '%s.Installment'%(y+1),foreground="green")
        t11.grid(row = y+2,column=0)    

    for y in range(number_of_installments.get()):
        ttt = Text(window, height=1, width=20, foreground="red")
        ttt.grid(row = y+2,column=1)
        
        #Net present values of the installments are calculated in this part.
        def NPV_calculation():
            interest_rate = [pow(1+0.0125,i) for i in range(1,int(number_of_installments.get())+1)]
            installment_amount = (float(list_price.get())-(float(list_price.get())*float(downpayment_percentage.get())))/(float(number_of_installments.get()))
            calculation = [installment_amount/i for i in interest_rate]
            ttt.insert(END,calculation)
           
        
    downpayment_calculation()
    NPV_calculation()  

#Downpayment calculated by entering a value between 0 to 1. For example if 0.2 is typed in the textbox it will multiply the list price by %20.
def downpayment_calculation():
    Downpayment = float(list_price.get())*float(downpayment_percentage.get())
    t0.insert(END,Downpayment)

#Entry boxes
number_of_installments = IntVar(value="")
installment = Entry(window, textvariable=number_of_installments)
installment.grid(row=3,column=3)

interest_value = StringVar()
interest = Entry(window, textvariable=interest_value)
interest.grid(row=0,column=3)

list_price = StringVar()
list = Entry(window, textvariable=list_price)
list.grid(row=1,column=3)

downpayment_percentage = StringVar()
downpayment = Entry(window, textvariable=downpayment_percentage)
downpayment.grid(row=2,column=3)

#Create button for creating number of grids based on the number of installments.
b1 = Button(window, text="Create", command=create)
b1.grid(row=0,column=4)

#Labels for the enrty boxes
n_installments = Label(window,text="Number Of Installments",foreground="blue")
n_installments.grid(row=3,column=2)

yearly_interest = Label(window,text="Yearly Interest",foreground="blue")
yearly_interest.grid(row=0,column=2)

price_list = Label(window,text="List Price",foreground="blue")
price_list.grid(row=1,column=2)

per_downpayment = Label(window,text="Downpayment Percentage",foreground="blue")
per_downpayment.grid(row=2,column=2)

#Label and text box for the downpayment
t0 = Label(window,text="Downpayment",foreground="green")
t0.grid(row=1,column=0) 

t0 = Text(window, height=1, width=20, foreground="red")
t0.grid(row=1,column=1)

window.mainloop()

当您调用 NPV_calculation 函数时,ttt 是最后一个文本小部件。


# This part asks the number of installments and creates the desired amount of text boxes.
def create():
    for y in range(number_of_installments.get()):
        t11 = Label(window,text= '%s.Installment'%(y+1),foreground="green")
        t11.grid(row = y+2,column=0)    

    for y in range(number_of_installments.get()):
        ttt = Text(window, height=1, width=20, foreground="red")
        ttt.grid(row = y+2,column=1)
        print("the object named ttt in this loop iteration is:", ttt)
        
        #Net present values of the installments are calculated in this part.
        def NPV_calculation():
            interest_rate = [pow(1+0.0125,i) for i in range(1,int(number_of_installments.get())+1)]
            installment_amount = (float(list_price.get())-(float(list_price.get())*float(downpayment_percentage.get())))/(float(number_of_installments.get()))
            calculation = [installment_amount/i for i in interest_rate]
            ttt.insert(END,calculation)
            print("the object named ttt is:", ttt)
        
    downpayment_calculation()
    NPV_calculation() # <- when you call this function, ttt is the last Text widget

number_of_installments = 3 的输出:


the object named ttt in this loop iteration is: .!text2
the object named ttt in this loop iteration is: .!text3
the object named ttt in this loop iteration is: .!text4
the object named ttt is: .!text4

在循环中创建文本小部件时需要插入值。最好将 NPV_calculation 函数移出循环。

这是自动生成值部分的简化示例。


import tkinter as tk


window = tk.Tk()

def do_n_calculation(n):
    calculation = [x+1 for x in range(n)]
    return calculation
    
def create():
    # get new values
    n = number_of_installments.get()
    calculation_list = do_n_calculation(n)
    
    # clear previous values
    for i in installment_frame.winfo_children():
        i.destroy()

    # insert new values
    for y in range(n):
        t11 = tk.Label(installment_frame, text= '%s.Installment'%(y+1), foreground="green")
        t11.grid(row=y, column=0)
    for y in range(n):
        ttt = tk.Text(installment_frame, height=1, width=20, foreground="red")
        ttt.grid(row=y, column=1)
        ttt.insert(tk.END, calculation_list[y])

label = tk.Label(window, text="Number Of Installments")
label.grid(row=0, column=0)

number_of_installments = tk.IntVar(value="")
entry = tk.Entry(window, textvariable=number_of_installments)
entry.grid(row=0, column=1)

button = tk.Button(window, text="Create", command=create)
button.grid(row=0, column=2)

installment_frame = tk.Frame(window)
installment_frame.grid(row=1, column=0)

window.mainloop()

使用 class 的完整示例。


import tkinter as tk


class Application(tk.Frame):
    """
          | column 0          | column 1   |
    -----------------------------------------
    row 0 | downpayment_frame | form_frame |
    -----------------------------------------
    row 1 | installment_frame |            |
    -----------------------------------------
    """
    def __init__(self, master):
        super().__init__(master)
        
        # data attributes
        self.downpayment_value = None
        self.calculation_list = None

        # left side
        
        # Label and text box for the downpayment
        self.downpayment_frame = tk.Frame(self)
        self.downpayment_frame.grid(row=0, column=0, padx=5, pady=5)
        
        self.downpayment_label = tk.Label(self.downpayment_frame, text="Downpayment", foreground="green")
        self.downpayment_label.grid(row=0, column=0) 

        self.downpayment_text = tk.Text(self.downpayment_frame, height=1, width=20, foreground="red")
        self.downpayment_text.grid(row=0, column=1)

        self.installment_frame = tk.Frame(self)
        self.installment_frame.grid(row=1, column=0, padx=5, pady=5)

        # right side

        self.form_frame = tk.Frame(self)
        self.form_frame.grid(row=0, column=1, padx=5, pady=5)
        
        # Labels for the enrty boxes
        self.yearly_interest = tk.Label(self.form_frame, text="Yearly Interest", foreground="blue")
        self.yearly_interest.grid(row=0, column=0)

        self.price_list = tk.Label(self.form_frame, text="List Price", foreground="blue")
        self.price_list.grid(row=1, column=0)

        self.per_downpayment = tk.Label(self.form_frame, text="Downpayment Percentage", foreground="blue")
        self.per_downpayment.grid(row=2, column=0)

        self.n_installments = tk.Label(self.form_frame, text="Number Of Installments", foreground="blue")
        self.n_installments.grid(row=3, column=0)
        
        # Entry boxes
        self.interest_value = tk.StringVar()
        self.interest = tk.Entry(self.form_frame, textvariable=self.interest_value)
        self.interest.grid(row=0, column=1)

        self.list_price = tk.StringVar()
        self.price = tk.Entry(self.form_frame, textvariable=self.list_price)
        self.price.grid(row=1, column=1)

        self.downpayment_percentage = tk.StringVar()
        self.downpayment = tk.Entry(self.form_frame, textvariable=self.downpayment_percentage)
        self.downpayment.grid(row=2, column=1)

        self.number_of_installments = tk.IntVar(value="")
        self.installment = tk.Entry(self.form_frame, textvariable=self.number_of_installments)
        self.installment.grid(row=3, column=1)

        # Create button for creating number of grids based on the number of installments.
        self.create_button = tk.Button(self.form_frame, text="Create", command=self.create)
        self.create_button.grid(row=0, column=2, rowspan=4, padx=[5, 0])

    # Net present values of the installments are calculated in this part.
    def NPV_calculation(self, number, list_price, percentage):
        interest_rate = [pow(1+0.0125,i) for i in range(1,int(number)+1)]
        installment_amount = (float(list_price)-(float(list_price)*float(percentage)))/(float(number))
        calculation = [installment_amount/i for i in interest_rate]
        return calculation
    
    def downpayment_calculation(self, list_price, percentage):
        downpayment = float(list_price)*float(percentage)
        return downpayment

    def create(self):
        number = self.number_of_installments.get()
        list_price = self.list_price.get()
        percentage = self.downpayment_percentage.get()

        # get new values and set data attributes
        self.downpayment_value = self.downpayment_calculation(list_price, percentage)
        self.calculation_list = self.NPV_calculation(number, list_price, percentage)

        # clear previous values
        self.downpayment_text.delete("1.0", tk.END)
        for i in self.installment_frame.winfo_children():
            i.destroy()
        
        # insert new values
        self.downpayment_text.insert(tk.END, self.downpayment_value)

        for y in range(number):
            label = tk.Label(self.installment_frame,text= '%s.Installment'%(y+1), foreground="green")
            label.grid(row=y, column=0)    

        for y in range(number):
            text = tk.Text(self.installment_frame, height=1, width=20, foreground="red")
            text.grid(row=y, column=1)
            text.insert(tk.END, self.calculation_list[y])
            
        self.get_calculation()

    def get_calculation(self):
        print(self.downpayment_value)
        print(self.calculation_list)


root = tk.Tk()
app = Application(master=root)
app.pack()
app.mainloop()