Python 在if/else语句上打开随机tkinter窗口

Python 在if/else语句上打开随机tkinter窗口,python,tkinter,Python,Tkinter,我想知道是不是我的if-else声明错了,还是这是一个tkinter问题。我希望这样,如果0留在任何或所有框中,它会给出一条错误消息。但在关闭错误消息后,它会打开一个随机空白窗口。这是我的密码。特定区域是函数valueget()中的if-else语句 首先,我建议提高if-else语句的可读性 coefficients = [readA, readB, readC] if sum(coefficients): # If they all are all zeros this wil

我想知道是不是我的if-else声明错了,还是这是一个tkinter问题。我希望这样,如果0留在任何或所有框中,它会给出一条错误消息。但在关闭错误消息后,它会打开一个随机空白窗口。这是我的密码。特定区域是函数valueget()中的if-else语句


首先,我建议提高if-else语句的可读性

coefficients = [readA, readB, readC]
if sum(coefficients):        # If they all are all zeros this will be False
    if min(coefficients):    # If any one is zero, this will be False
        label = tk.Label(messagewindow, text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}', bg='#aaf0d1', font = ('verdana'))
        label.grid(row=1)
        closebutton = tk.Button(messagewindow, text='Close', command = lambda: messagewindow.destroy(), font = ('verdana'), highlightbackground='#aaf0d1')
        closebutton.grid(row=2)
        closebutton.config(bg='#aaf0d1')
    else:
        errorwindow = tk.messagebox.showerror(message='none').pack()
else:
    errorwindow = tk.messagebox.showerror(message='none').pack()

以下是我将要做的基本想法:

import tkinter as tk
from tkinter import messagebox

def mainwindow(root):
    # Creates a toplevel window
    mainwindow = tk.Toplevel()
    mainwindow.protocol("WM_DELETE_WINDOW", root.destroy) # This overrides the "X" being clicked to also destroy the root window.
    root.withdraw() # "Hides" the root window, leaving it (and mainloop) running in the background.
    mainwindow.title('Enter values')
    mainwindow.geometry('160x110')
    mainwindow.config(bg='#aaf0d1')

    # Since all three of the labels/entries are the same
    # we can save space by generating them in a loop
    entry_items = ('Enter a', 'Enter b', 'Enter c')
    values = []
    for x, item in enumerate(entry_items): # Using enumerate and x to assign rows
        tk.Label(mainwindow, text = item,
                 font = ('verdana'),  bg='#aaf0d1').grid(row=x) # Row assigned to x.

        values.append(tk.StringVar()) # Appended StringVar to list.
        tk.Entry(mainwindow,
                 textvariable = values[-1], # Uses the last value appended to the values list.
                 highlightbackground='#aaf0d1',
                 width=3,
                 bg='#aaf0d1').grid(row=x, column=1) # Row assigned to x.     

    tk.Button(mainwindow,
              text='Obtain roots',
              command = lambda vals = values: valueget(vals), # Here the button command is assigned with the values list
              font = ('verdana'), bg='#aaf0d1',
              highlightbackground='#aaf0d1').grid(row=3) # we know there are 3 items before this.

    mainwindow.lift() # This is a method of bringing a window to the front

def valueget(vals):
    # This line gets the values from the StringVars, converts them to ints,
    # and returns them to their respective variables.
    try:
        readA, readB, readC = [int(val.get()) for val in vals]
    except ValueError:
        messagebox.showerror(title="Number Error", message='Values must be numbers')
        return

    # Here the variables are checked to see if they are 0
    # Since each one is being checked if it is 0, there is no need to check if they are all 0.
    for val in (readA, readB, readC):
        if val == 0:
            # If they are 0, shows an error message
            messagebox.showerror(title="Zero Error", message='Values must not be zero')
            return

    # Creates a toplevel to display the results
    messagewindow = tk.Toplevel()
    messagewindow.title('Roots of the equation')
    messagewindow.config(bg='#aaf0d1')

    negroot = (readB**2)-(4*readA*readC)

    quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
    quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla

    tk.Label(messagewindow,
             text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}',
             bg='#aaf0d1',
             font = ('verdana')).pack(padx = 5, pady = 2)

    tk.Button(messagewindow,
              text='Close',
              command = messagewindow.destroy, # There is no need for a lambda for this.
              font = ('verdana'),
              bg = '#aaf0d1',
              highlightbackground='#aaf0d1').pack(padx = 5, pady = 2)

    # print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')

    messagewindow.lift() # This is a method of bringing a window to the front

def startup():
    startpage = tk.Tk()
    startpage.title('Solver')
    # COMMENTED OUT FOR TESTING
    #photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png")  #image load
    coverbutton = tk.Button(startpage,
                            # COMMENTED OUT FOR TESTING
                            #image = photo,
                            text = "TESTING", # HERE FOR TESTING
                            highlightbackground='#aaf0d1',
                            command = lambda root = startpage: mainwindow(root)).pack() # Passes the startpage to the mainwindow function.

    startpage.mainloop() # The only mainloop you need.

startup()

不要使用太多的
Tk()
实例。这会导致一些问题。使用toplevel并没有解决它@jizhaosama使用tkinter导入中的
*
不是一个好做法。而且您还使用了
导入tkinter作为tk
。您将
getA
定义为函数
主窗口中的局部变量。它肯定不能用于函数
valueget
@squashguy919:,从技术上讲,如果您已经在检查它们中是否有任何一个是
0
,那么它们是否都是又有什么关系呢?您好。谢谢,但不是最有用的。我不知道你采取了什么方法,我想知道在我所做的三个
mainloop()实例中我哪里出了问题
,局部变量冲突,过度使用
lambda
调用,不正确使用
tk.messagebox
,缩进不一致,代码冗余/重复。对于您编写的代码,我得到的第一个错误是
zerodivision错误:在检查值是否为零之前进行除法操作导致的浮点除法。@squashguy919我添加了一堆注释来帮助解释。
import tkinter as tk
from tkinter import messagebox

def mainwindow(root):
    # Creates a toplevel window
    mainwindow = tk.Toplevel()
    mainwindow.protocol("WM_DELETE_WINDOW", root.destroy) # This overrides the "X" being clicked to also destroy the root window.
    root.withdraw() # "Hides" the root window, leaving it (and mainloop) running in the background.
    mainwindow.title('Enter values')
    mainwindow.geometry('160x110')
    mainwindow.config(bg='#aaf0d1')

    # Since all three of the labels/entries are the same
    # we can save space by generating them in a loop
    entry_items = ('Enter a', 'Enter b', 'Enter c')
    values = []
    for x, item in enumerate(entry_items): # Using enumerate and x to assign rows
        tk.Label(mainwindow, text = item,
                 font = ('verdana'),  bg='#aaf0d1').grid(row=x) # Row assigned to x.

        values.append(tk.StringVar()) # Appended StringVar to list.
        tk.Entry(mainwindow,
                 textvariable = values[-1], # Uses the last value appended to the values list.
                 highlightbackground='#aaf0d1',
                 width=3,
                 bg='#aaf0d1').grid(row=x, column=1) # Row assigned to x.     

    tk.Button(mainwindow,
              text='Obtain roots',
              command = lambda vals = values: valueget(vals), # Here the button command is assigned with the values list
              font = ('verdana'), bg='#aaf0d1',
              highlightbackground='#aaf0d1').grid(row=3) # we know there are 3 items before this.

    mainwindow.lift() # This is a method of bringing a window to the front

def valueget(vals):
    # This line gets the values from the StringVars, converts them to ints,
    # and returns them to their respective variables.
    try:
        readA, readB, readC = [int(val.get()) for val in vals]
    except ValueError:
        messagebox.showerror(title="Number Error", message='Values must be numbers')
        return

    # Here the variables are checked to see if they are 0
    # Since each one is being checked if it is 0, there is no need to check if they are all 0.
    for val in (readA, readB, readC):
        if val == 0:
            # If they are 0, shows an error message
            messagebox.showerror(title="Zero Error", message='Values must not be zero')
            return

    # Creates a toplevel to display the results
    messagewindow = tk.Toplevel()
    messagewindow.title('Roots of the equation')
    messagewindow.config(bg='#aaf0d1')

    negroot = (readB**2)-(4*readA*readC)

    quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
    quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla

    tk.Label(messagewindow,
             text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}',
             bg='#aaf0d1',
             font = ('verdana')).pack(padx = 5, pady = 2)

    tk.Button(messagewindow,
              text='Close',
              command = messagewindow.destroy, # There is no need for a lambda for this.
              font = ('verdana'),
              bg = '#aaf0d1',
              highlightbackground='#aaf0d1').pack(padx = 5, pady = 2)

    # print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')

    messagewindow.lift() # This is a method of bringing a window to the front

def startup():
    startpage = tk.Tk()
    startpage.title('Solver')
    # COMMENTED OUT FOR TESTING
    #photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png")  #image load
    coverbutton = tk.Button(startpage,
                            # COMMENTED OUT FOR TESTING
                            #image = photo,
                            text = "TESTING", # HERE FOR TESTING
                            highlightbackground='#aaf0d1',
                            command = lambda root = startpage: mainwindow(root)).pack() # Passes the startpage to the mainwindow function.

    startpage.mainloop() # The only mainloop you need.

startup()