如何通过“提交”按钮获取输入然后打印为文本?

时间:2019-06-08 09:57:28

标签: python python-3.x tkinter

首先,对不起代码错误,我是菜鸟!但是,我正在修改一些tkinter,并且几乎用代码达到了我的目标……但是我似乎无法弄清楚如何在按下按钮时将输入字段中的输入转换为文本框。

代码似乎可以正常工作,因为我在终端中获得了所需的输出,而不是在tkinter窗口中。我尝试使用普通的文本框和scrolledtext。

import tkinter as tk
from tkinter import scrolledtext

fields = ('Principal', 'Expected Return', 'Number of Years', 'Yearly Payment', 'Cost Rate') #fields for gui

def some_logics(entry_from_user):
    #grab input from user from fields
    principal = int(entry_from_user['Principal'].get()) 
    rate_return = float(entry_from_user['Expected Return'].get()) /100
    number_periods = int(entry_from_user['Number of Years'].get())
    pmt = int(entry_from_user['Yearly Payment'].get())
    rate_cost = float(entry_from_user['Cost Rate'].get()) /100

    #main function, utilizes variables to calculcate and print out desired text
    def print_out():

        #investment return, initial investment, expected yearly return, number of years, yearly payment
        def accrued(principal, rate_return, number_periods, pmt=0):
            cash = principal
            for periods in range(number_periods):
                cash += (cash * rate_return) + pmt
            return cash

        #if capital is borrowed insert capital, cost of capital and number of years
        def cost_of_capital(principal, rate_cost, number_periods):
            effective_cost_rate = (1 + (rate_cost/12))**12 - 1
            return principal * effective_cost_rate * number_periods


        end_cash = accrued(principal, rate_return, number_periods, pmt) #calculate total end sum for investment
        cost_capital_end = cost_of_capital(principal, rate_cost, number_periods) #calculate total cost of capital
        print(end_cash)
        print(cost_capital_end)
        print(f'Initial investment was {principal}, while after the period cash is {end_cash}. This is a total gain of {end_cash - principal}')
        print(f'Of the total gain {pmt * number_periods} was coming from the installments. This results in a net gain of {end_cash - principal - (pmt * number_periods)}')
        print(f'Cost of investment is: {cost_capital_end} and this shows a actual gain of {(end_cash - principal - (pmt * number_periods)) - cost_capital_end}')

    return print_out()

def makeform(root, fields):
    #create a dictionary for fields
    entries = {} 
    for field in fields:
        print(field)
        row = tk.Frame(root)
        lab = tk.Label(row, width=22, text=field+": ", anchor='w')
        ent = tk.Entry(row)
        ent.insert(0, "0")
        row.pack(side = tk.TOP, fill = tk.X, padx = 5, pady = 5)
        lab.pack(side = tk.LEFT)
        ent.pack(side = tk.RIGHT, expand = tk.YES, fill = tk.X)
        entries[field] = ent
    return entries

if __name__ == '__main__':
    root = tk.Tk() #initialize object
    ents = makeform(root, fields) #create form
    #create a button, button is placing user input into funcion
    b1 = tk.Button(root, text='Calculate',
        command = (lambda e=ents: some_logics(e)))
    b1.pack(side=tk.LEFT, padx = 5, pady = 5)
    #create a quit program button
    b2 = tk.Button(root, text='Quit', command=root.quit)
    b2.pack(side=tk.RIGHT, padx=5, pady=5)
    #create a textfield which returns user input in format from print_out function
    T = scrolledtext.ScrolledText(root, state='disabled')
    T.pack(side= tk.BOTTOM, padx=5, pady=5)
    T.insert(tk.END, (lambda e=ents: some_logics(e)))
    root.mainloop()

奖金问题:我将代码重构为嵌套函数,这是pythonic还是仅仅是噪音?

1 个答案:

答案 0 :(得分:1)

我认为嵌套函数很吵,是。

我在这里所做的更改是:

  • 使用Black自动格式化
  • main()函数中包装主要逻辑以避免使用全局变量
  • 将嵌套函数取消嵌套为自由函数(它们实际上属于模块中)
  • 将输出生成函数重构为自由函数
  • 使update_form(néesome_logics)函数接受应更新(并实际上对其进行更新)的输出字段
  • 修复lambda的非常规使用

希望这会有所帮助。

import tkinter as tk
from tkinter import scrolledtext

fields = (
    "Principal",
    "Expected Return",
    "Number of Years",
    "Yearly Payment",
    "Cost Rate",
)  # fields for gui


# investment return, initial investment, expected yearly return, number of years, yearly payment
def accrued(principal, rate_return, number_periods, pmt=0):
    cash = principal
    for periods in range(number_periods):
        cash += (cash * rate_return) + pmt
    return cash


# if capital is borrowed insert capital, cost of capital and number of years
def cost_of_capital(principal, rate_cost, number_periods):
    effective_cost_rate = (1 + (rate_cost / 12)) ** 12 - 1
    return principal * effective_cost_rate * number_periods


def calculate_output(number_periods, pmt, principal, rate_cost, rate_return):
    end_cash = accrued(
        principal, rate_return, number_periods, pmt
    )  # calculate total end sum for investment
    cost_capital_end = cost_of_capital(
        principal, rate_cost, number_periods
    )  # calculate total cost of capital
    output = "\n".join(
        (
            f"Initial investment was {principal}, while after the period cash is {end_cash}. This is a total gain of {end_cash - principal}",
            f"Of the total gain {pmt * number_periods} was coming from the installments. This results in a net gain of {end_cash - principal - (pmt * number_periods)}",
            f"Cost of investment is: {cost_capital_end} and this shows a actual gain of {(end_cash - principal - (pmt * number_periods)) - cost_capital_end}",
        )
    )
    return output


def update_form(entry_from_user, output_field):
    # grab input from user from fields
    principal = int(entry_from_user["Principal"].get())
    rate_return = float(entry_from_user["Expected Return"].get()) / 100
    number_periods = int(entry_from_user["Number of Years"].get())
    pmt = int(entry_from_user["Yearly Payment"].get())
    rate_cost = float(entry_from_user["Cost Rate"].get()) / 100

    output = calculate_output(number_periods, pmt, principal, rate_cost, rate_return)
    output_field.delete("1.0", tk.END)  # clear
    output_field.insert(tk.INSERT, output)


def makeform(root, fields):
    # create a dictionary for fields
    entries = {}
    for field in fields:
        row = tk.Frame(root)
        lab = tk.Label(row, width=22, text=field + ": ", anchor="w")
        ent = tk.Entry(row)
        ent.insert(0, "0")
        row.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
        lab.pack(side=tk.LEFT)
        ent.pack(side=tk.RIGHT, expand=tk.YES, fill=tk.X)
        entries[field] = ent
    return entries


def main():
    root = tk.Tk()  # initialize object

    output_field = scrolledtext.ScrolledText(root)  # create output field

    ents = makeform(root, fields)  # create form
    # create a button, button is placing user input into funcion
    b1 = tk.Button(
        root, text="Calculate", command=lambda: update_form(ents, output_field)
    )
    b1.pack(side=tk.LEFT, padx=5, pady=5)
    # create a quit program button
    b2 = tk.Button(root, text="Quit", command=root.quit)
    b2.pack(side=tk.RIGHT, padx=5, pady=5)
    # create a textfield which returns user input in format from print_out function
    output_field.pack(side=tk.BOTTOM, padx=5, pady=5)
    root.mainloop()


if __name__ == "__main__":
    main()