Python 3.x 向tkinter代码添加验证

Python 3.x 向tkinter代码添加验证,python-3.x,tkinter,Python 3.x,Tkinter,我正在用tkinter做一个GUI 在代码的第2帧上,我有一个条目小部件。我只希望数字是有效的。如果按下按钮后在输入小部件中输入字母、特殊字符、符号、空格等,如何在文本小部件中打印错误消息?在python中,我使用了While True,但我不知道这是否可以在tkinter中使用,也不知道我是否会将验证放在代码中 我的代码如下 import tkinter as tk # python 3 from tkinter import font as tkfont #

我正在用tkinter做一个GUI

在代码的第2帧上,我有一个条目小部件。我只希望数字是有效的。如果按下按钮后在输入小部件中输入字母、特殊字符、符号、空格等,如何在文本小部件中打印错误消息?在python中,我使用了While True,但我不知道这是否可以在tkinter中使用,也不知道我是否会将验证放在代码中

我的代码如下

import tkinter as tk                # python 3
from tkinter import font  as tkfont # python 3 
from tkinter import StringVar
import pandas as pd
from tkinter import ttk

df = {"Option B":[0,10,25,100,120,140,160,200,500,800,1200,1700,2000],
    "Option A":[0,0,15,90,110,130,150,190,490,790,1190,1690,1990]}
price_options = pd.DataFrame(df,index=["0",
                        "1 - 50",
                        "51 to 75",
                        "76 to 90",
                        "91 to 100",
                        "101 to 110",
                        "111 to 130",
                        "131 to 150",
                        "151 to 170",
                        "171 to 190",
                        "191 to 225",
                        "226 to 255",
                        "Over 255"])


class My_GUI(tk.Tk):

def __init__(self, *args, **kwargs):
    tk.Tk.__init__(self, *args, **kwargs)

    self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")

    # the container is where we'll stack a bunch of frames
    # on top of each other, then the one we want visible
    # will be raised above the others
    container = tk.Frame(self)
    container.pack(side="top", fill="both", expand=True)
    container.grid_rowconfigure(0, weight=1)
    container.grid_columnconfigure(0, weight=1)

    self.frames = {}
    for F in (StartPage, Page2, Page3):
        page_name = F.__name__
        frame = F(parent=container, controller=self)
        self.frames[page_name] = frame

        # put all of the pages in the same location;
        # the one on the top of the stacking order
        # will be the one that is visible.
        frame.grid(row=0, column=0, sticky="nsew")

    self.show_frame("StartPage")

def show_frame(self, page_name):
    #Show a frame for the given page name
    frame = self.frames[page_name]
    frame.tkraise()

class StartPage(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller
    label = tk.Label(self, text="Welcome.....\nCheck how much it will cost......\n", font=controller.title_font)
    label.pack(side="top", fill="x", pady=10)

    button1 = tk.Button(self, text="Item A",
                        command=lambda: controller.show_frame("Page2"))
    button2 = tk.Button(self, text="Item B",
                        command=lambda: controller.show_frame("Page3"))
    button1.pack()
    button2.pack()

class Page2(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller
    label = tk.Label(self, text="Select from the options below", font=controller.title_font)
    label.pack(side="top", fill="x", pady=10)

    global df
    tk.Label(self, text='Select option:').pack()
    self.options = ttk.Combobox(self, values=list(price_options.columns))
    self.options.pack()




    label = tk.Label(self, text="How much does the item weigh?", font=controller.title_font)
    label.pack()

    self.weight_entry = tk.Entry(self)
    self.weight_entry.pack()

    tk.Button(self, text='Click here to display price', command=self.show_option).pack()

    self.text = tk.Text(self)
    self.text.pack()

    tk.Button(self, text="Restart",
              command=lambda: controller.show_frame("StartPage")).pack()

def show_option(self):
    identifier = self.options.get() # get option
    weight_id = int(self.weight_entry.get())
    self.text.delete(1.0, tk.END)   # empty widget to print new text
    #self.text.insert(tk.END, str(price_options[identifier]))


    if identifier == "Option B":

        if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,1:2]))
        elif weight_id >= 1 and weight_id <= 50: self.text.insert(tk.END, str(price_options.iloc[1:2,1:2]))
        elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,1:2]))

    elif identifier == "Option A":
        if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,:1]))
        elif weight_id >= 1 and weight_id <= 50 : self.text.insert(tk.END, str(price_options.iloc[1:2,:1]))
        elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,:1]))


class Page3(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller
    label = tk.Label(self, text="Some text here...", font=controller.title_font)
    label.pack(side="top", fill="x", pady=10)
    button = tk.Button(self, text="Go to the start page",
                       command=lambda: controller.show_frame("StartPage"))
    button.pack()        

if __name__ == "__main__":
app = My_GUI()
app.mainloop()

您可以用try/except包装输入,int函数会自动去除外部空间。数字和任何非数字字符之间的空格将引发错误

    def show_option(self):
        identifier = self.options.get() # get option
        try:
            weight_id = int(self.weight_entry.get())
            self.text.delete(1.0, tk.END)   # empty widget to print new text
            if identifier == "Option B":

                if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,1:2]))
                elif weight_id >= 1 and weight_id <= 50: self.text.insert(tk.END, str(price_options.iloc[1:2,1:2]))
                elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,1:2]))

            elif identifier == "Option A":
                if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,:1]))
                elif weight_id >= 1 and weight_id <= 50 : self.text.insert(tk.END, str(price_options.iloc[1:2,:1]))
                elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,:1]))            
        except:
            self.text.delete(1.0, tk.END)
            self.text.insert(1.0, 'Wrong input')

条目小部件具有验证选项,仅允许将有效输入添加到条目中。也就是说,如果用户尝试在条目中键入字母或任何其他非数字字符,它们将不会显示:

class Page2(tk.Frame):

    def __init__(self, parent, controller):
        ...

        vcmd = (self.register(self.onValidate), '%S')
        self.weight_entry = tk.Entry(self, validate='key', vcmd=vcmd)
        self.weight_entry.pack()

        ...

    def onValidate(self, S):
        if S in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
            return True
        else:
            # output warning message here
            return False

    def show_option(self):
        ...

谢谢你的解决方案。工作完美。我将在我的代码中使用它。你的缩进是混乱的,你发布了太多与所问问题完全无关的代码。