在点击按钮之前,Tkinter的第二个窗口会自动弹出

编程语言 2026-07-10

我以为 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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章