Python 3.x 向tkinter代码添加验证
我正在用tkinter做一个GUI 在代码的第2帧上,我有一个条目小部件。我只希望数字是有效的。如果按下按钮后在输入小部件中输入字母、特殊字符、符号、空格等,如何在文本小部件中打印错误消息?在python中,我使用了While True,但我不知道这是否可以在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 #
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):
...
谢谢你的解决方案。工作完美。我将在我的代码中使用它。你的缩进是混乱的,你发布了太多与所问问题完全无关的代码。