在点击按钮之前,Tkinter的第二个窗口会自动弹出
我以为 if 语句表示用户需要按下按钮,程序才会检查输入框中是否输入了非浮点数或非整数,从而触发打开另一个窗口;但它在我启动应用时会自动弹出。
import tkinter as tk
import math
from tkinter import *
window = tk.Tk()
window.title('Mortgage Calculator')
# How much is the property?
property_price = tk.Label(
window, text="How much is the property? ", font=("Arial", 11))
property_price.pack(pady=10)
property_price_entry = tk.Entry(window, text="How much is the property?", font=("Arial", 11))
property_price_entry.pack(pady=10,)
# side string next to entry
# How much do you want to pay as a deposit?
property_deposit = tk.Label(
window, text="How much do you want to pay as a deposit?", font=("Arial", 11))
property_deposit.pack(pady=10)
property_deposit_entry = tk.Entry(window, font=("Arial", 11))
property_deposit_entry.pack(pady=10)
# How many years will the term on your mortgage be?
years_of_mortgage = tk.Label(
window, text="How many years will the term be on your mortgage?", font=("Arial", 11), )
years_of_mortgage.pack(pady=10)
years_of_mortgage_entry = tk.Entry(window, font=("Arial", 11))
years_of_mortgage_entry.pack(pady=10)
# How much is the annual interest rate?
interest = tk.Label(
window, text="How much is the annual interest rate?", font=("Arial", 11))
interest.pack(pady=10)
interest_entry = tk.Entry(window,font=("Arial", 11))
interest_entry.pack(pady=10)
# Define a button function
def calculate_mortgage_button():
principlal = float(property_price_entry.get())
deposit = float(property_deposit_entry.get())
principlal = principlal - deposit
annual_interest_rate = float(interest_entry.get())/100
term = float(years_of_mortgage_entry.get())
monthly_payment = principlal * \
(annual_interest_rate/12)/1-(1 + annual_interest_rate/12)**-12*term
monthly_payment = round(monthly_payment, 2)
monthly_payment_label = tk.Label(window, text=f"Your monthly payments are: £{monthly_payment}", font=("Arial", 11))
monthly_payment_label.pack(pady=10)
# Mortgage calculator button
mortgage_button = tk.Button(
window, text='Calculate monthly mortgage payments', command=calculate_mortgage_button)
mortgage_button.config(command=calculate_mortgage_button)
mortgage_button.config(font=('Arial', 11))
mortgage_button.pack(pady=10)
# error window
if calculate_mortgage_button != float or calculate_mortgage_button == str:
error_window = Label(window, text="Please enter a number only.").pack(pady=20)
window.mainloop()
我希望只有当用户输入字符串数据类型时,窗口才会出现在屏幕上。
解决方案
Button(以及其他控件)不像 input() 那样工作,它不会等待用户按下。它只是创建要在窗口中显示的信息,而 mainloop() 会创建窗口并显示这些控件。因此在 mainloop() 之前的所有内容在你真正打开窗口之前就已经执行。
如果你想在按下按钮后执行某些操作,则必须直接在由 command= 指定的函数中完成。
Code calculate_mortgage_button != float 不会检查值是否为 float。
如果你想检查变量中的值是否为 float,你需要 isinstance(calculate_mortgage_button, float),但你需要另一种做法。
你必须检查来自Entry的 string 是否可以在不出错的情况下转换为 float。这需要在 try/except 中使用 float(text) 来捕获异常 ValueError。
def calculate_mortgage_button():
try:
principlal = float(property_price_entry.get())
deposit = float(property_deposit_entry.get())
interest = float(interest_entry.get())
term = float(years_of_mortgage_entry.get())
except ValueError as ex:
error_window = tk.Label(window, text="Please enter a number only.")
error_window.pack(pady=20)
return # exit function without calculations.
# ... calculations
如果你想要更多细节,可以把每个 float() 放到单独的 try/except 中
def calculate_mortgage_button():
correct_values = True
try:
principlal = float(property_price_entry.get())
except ValueError as ex:
error_window = tk.Label(window, text="Please enter a number only for property_price.")
error_window.pack(pady=20)
correct_values = False
try:
deposit = float(property_deposit_entry.get())
except ValueError as ex:
error_window = tk.Label(window, text="Please enter a number only for property_deposit.")
error_window.pack(pady=20)
correct_values = False
# ... etc ...
if not correct_values:
return # exit function without calculations.
# ... calculations
另一个问题是在移除带有错误信息的标签时,因为再次按下按钮时它会添加新的标签而不会移除旧的标签。
你可以在开始时创建 tk.Frame
message_frame = tk.Frame(window)
message_frame.pack()
然后把带有消息的标签放在这个帧中。
tk.Label(message_frame, ...)
并且当你按下按钮时,从这个帧中移除所有子控件
def calculate_mortgage_button():
# remove previous messages
for child in message_frame.winfo_children():
child.destroy()
完整可运行的代码:
import tkinter as tk
# from tkinter import * # PEP8: `import *` is not preferred
# --- functions ---
def calculate_mortgage_button():
# remove previous messages
for child in message_frame.winfo_children():
child.destroy()
# ---
correct_values = True
try:
principlal = float(property_price_entry.get())
except ValueError as ex:
error_window = tk.Label(
message_frame, text="Please enter a number only for property price."
)
error_window.pack()
correct_values = False
try:
deposit = float(property_deposit_entry.get())
except ValueError as ex:
error_window = tk.Label(
message_frame, text="Please enter a number only for property deposit."
)
error_window.pack()
correct_values = False
try:
interest = float(interest_entry.get())
except ValueError as ex:
error_window = tk.Label(
message_frame, text="Please enter a number only for interest."
)
error_window.pack()
correct_values = False
try:
term = float(years_of_mortgage_entry.get())
except ValueError as ex:
error_window = tk.Label(
message_frame, text="Please enter a number only for term."
)
error_window.pack()
correct_values = False
if not correct_values:
return
# calculations
principlal = principlal - deposit
annual_interest_rate = interest / 100
monthly_payment = (
principlal * (annual_interest_rate / 12) / 1
- (1 + annual_interest_rate / 12) ** -12 * term
)
monthly_payment = round(monthly_payment, 2)
monthly_payment_label = tk.Label(
message_frame,
text=f"Your monthly payments are: £{monthly_payment}",
font=my_font,
)
monthly_payment_label.pack(pady=10)
# --- main ---
my_font = ("Arial", 11)
window = tk.Tk()
window.title("Mortgage Calculator")
# How much is the property?
property_price = tk.Label(window, text="How much is the property? ", font=my_font)
property_price.pack(pady=10)
property_price_entry = tk.Entry(window, text="How much is the property?", font=my_font)
property_price_entry.pack(
pady=10,
)
# How much do you want to pay as a deposit?
property_deposit = tk.Label(
window, text="How much do you want to pay as a deposit?", font=my_font
)
property_deposit.pack(pady=10)
property_deposit_entry = tk.Entry(window, font=my_font)
property_deposit_entry.pack(pady=10)
# How many years will the term on your mortgage be?
years_of_mortgage = tk.Label(
window, text="How many years will the term be on your mortgage?", font=my_font
)
years_of_mortgage.pack(pady=10)
years_of_mortgage_entry = tk.Entry(window, font=my_font)
years_of_mortgage_entry.pack(pady=10)
# How much is the annual interest rate?
interest = tk.Label(window, text="How much is the annual interest rate?", font=my_font)
interest.pack(pady=10)
interest_entry = tk.Entry(window, font=my_font)
interest_entry.pack(pady=10)
# Mortgage calculator button
mortgage_button = tk.Button(
window,
font=my_font,
text="Calculate monthly mortgage payments",
command=calculate_mortgage_button,
)
mortgage_button.pack(pady=10)
# frame for all messages
message_frame = tk.Frame(window)
message_frame.pack()
window.mainloop()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。