《零基础入门学习Python》第067讲:GUI的终极选择:Tkinter4
作者:互联网
今天我们来学习 Entry 组件,也就是我们平时所说的 输入框。
输入框是跟程序打交道的途径,比如 程序要求你输入 账号 和 密码。那么它就要提供两个输入框,并且接收密码的输入框还会用 星号 * 将实际的内容给隐藏起来。
我们学了还几个 tkinter 的组件之后,你自然就会发现,其实,很多方法和选项,它们之间都是通用的,这些选项对于不同的组件来说,名字一样,内容也一样。比如说,在输入框中,用代码增加和删除内容,也就是使用 insert() 和 delete() 方法。
创建一个输入框
我们来尝试一下:
import tkinter as tk
master = tk.Tk()
e1 = tk.Entry(master)
e1.pack(padx=10,pady=10)
master.mainloop()
运行一下:
就得到了一个输入框,我们可以在里面填写任意的字符,当字符太长时,它会自动滚动。
我们这里试一下 :
e.delete(0, END) (这就是清空输入框)
e.insert(0, "默认文本...")
import tkinter as tk
master = tk.Tk()
e1 = tk.Entry(master)
e1.pack(padx=10,pady=10)
e1.delete(0,'end') #删除输入框中的第0个到最后一个字符
e1.insert(0,'默认文本...') #在索引下标为0的地方插入"默认文本..."
master.mainloop()
运行一下:
那我们如何获取输入框中的内容呢?
我们可以使用 Entry 组件的 get() 方法,和之前的方法也是一样的。
你也可以将一个 tkinter 的变量(通常是一个 StringVar 变量)挂钩到 textvariable 选项,然后通过变量的 get() 方法来获取。
下面这个例子 ,就要实现如图的效果,按 获取信息 按钮时,会清空输入框,然后打印信息。
当我们按下 获取信息 按钮时:
我们一起来实现吧:
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root)
frame.pack(padx=10,pady=10)
lable1 = tk.Label(frame,text='作品: ').grid(row=0,column=0)
label2 = tk.Label(frame,text='作者: ').grid(row=1,column=0)
e1 = tk.Entry(frame)
e1.grid(row=0,column=1,padx=10,pady=5)
e2 = tk.Entry(frame)
e2.grid(row=1,column=1,padx=10,pady=5)
#这里要注意:上面的话不能写成如下所示
#e1 = tk.Entry(frame).grid(row=0,column=1,padx=10,pady=5)
#如果像上面一样写的话会导致e1是一个空对象,空对象没有get()方法
def show() :
print("作品:《%s》" %e1.get())
print("作者:%s" %e2.get())
e1.delete(0,'end')
e2.delete(0,'end')
button1 = tk.Button(frame,text='获取信息',width=10,command=show)\
.grid(row=3,column=0,sticky='w',padx=10,pady=10)
button2 = tk.Button(frame,text='退出',width=10,command=frame.quit)\
.grid(row=3,column=1,sticky='e',padx=10,pady=10)
root.mainloop()
我们首先生成两个 Label ,来自于 root 窗口,显示作品和作者,关于布局,我们传统的做法是用两个 Frame 把它包围起来,现在教你一个新的方法,tkinter 总共提供了三种不同的 布局组件的方法,一种就是我们熟悉的 pack,还有一种就是 grid (网格),就是使用表格的形式来管理你的组件。另一种就是 place(在后面的笔记中介绍)。
grid() 是允许你使用表格的形式来管理组件的位置,它有选项 row 表示 行,column 表示 列。(行数列数都是从0开始。)
然后是生成两个输入框。
最后是添加两个按钮。第一个是 “获取信息”,设置宽度 width ,command 为**show()函数,另一个是“退出”**按钮,我们直接调用 quit() 方法即可。
关于按钮的布局,因为我们不仅要放在最后一行,还要分别靠左、靠右,这就需要设置 grid() 的 sticky 选项
sticky 用法
1. 控制组件在 grid 分配的空间中的位置
2. 可以使用 “n”, “e”, “s”, “w” 以及它们的组合来定位(ewsn代表东西南北,上北下南左西右东)
3. 使用加号(+)表示拉长填充,例如 “n” + “s” 表示将组件垂直拉长填充网格,“n” + “s” + “w” + “e” 表示填充整个网格
4. 不指定该值则居中显示
然后我们运行程序:
当我们按下 获取信息 时,
但是当我们按 退出 按钮时,没有任何反应,这是为什么呢?
这是因为 我们使用的 IDLE 也是使用 tkinter 写出来的,这里会发生冲突。我们可以直接 右键使用Python直接运行 该程序,就会正常工作了。
接下来就是如何设计一个密码输入框(用星号*代替你实际输入的内容)。
这个很简单,我们只需要设置一个 show 选项就可以了。
show 用法
1. 设置输入框如何显示文本的内容
2. 如果该值非空,则输入框会显示指定字符串代替真正的内容
3. 将该选项设置为 “*”,则是密码输入框(你这是为什么字符,就以什么字符代替
我们直接在上面的代码上修改:
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root)
frame.pack(padx=10,pady=10)
string1 = tk.StringVar()
string2 = tk.StringVar()
lable1 = tk.Label(frame,text='账号: ').grid(row=0,column=0)
label2 = tk.Label(frame,text='密码: ').grid(row=1,column=0)
e1 = tk.Entry(frame,textvariable=string1)
e1.grid(row=0,column=1,padx=10,pady=5)
e2 = tk.Entry(frame,textvariable=string2,show='*')
e2.grid(row=1,column=1,padx=10,pady=5)
#这里要注意:上面的话不能写成如下所示
#e1 = tk.Entry(frame).grid(row=0,column=1,padx=10,pady=5)
#如果像上面一样写的话会导致e1是一个空对象,空对象没有get()方法
def show() :
print("账号:%s" %e1.get())
print("密码:%s" %e2.get())
#e1.delete(0,'end')
#e2.delete(0,'end')
button1 = tk.Button(frame,text='获取信息',width=10,command=show)\
.grid(row=3,column=0,sticky='w',padx=10,pady=10)
button2 = tk.Button(frame,text='退出',width=10,command=frame.quit)\
.grid(row=3,column=1,sticky='e',padx=10,pady=10)
root.mainloop()
这里我们还使用了另一种获取输入框内容的方法:“你也可以将一个 tkinter 的变量(通常是一个 StringVar 变量)挂钩到 textvariable 选项,然后通过变量的 get() 方法来获取。”
运行一下:
基本的问题都解决了。
接下来我们试图设计一个计算器,大家都知道,计算器不能够输入除了数字之外的任何字符,这又该如何限制呢?
这也是可以实现的,Entry 本身就自带了 验证功能。用于验证输入框里的内容的合法性,比如要求输入数字,你输入了字母那就是非法。实现该功能,需要通过设置 validate 、 validatecommand 和 invalidcommand 选项。
首先启用验证的“开关”是 validate 选项,该选项可以设置的值有:(焦点指的就是 输入字符的光标)
值 | 含义 |
'focus' | 当 Entry 组件获得或失去焦点的时候验证 |
'focusin' | 当 Entry 组件获得焦点的时候验证 |
'focusout' | 当 Entry 组件失去焦点的时候验证 |
'key' | 当输入框被编辑的时候验证 |
'all' | 当出现上边任何一种情况的时候验证 |
'none' | 1. 关闭验证功能 2. 默认设置该选项(即不启用验证) 3. 注意,是字符串的 'none',而非 None |
其次是为 validatecommand 选项指定一个验证函数,该函数只能返回 True 或 False 表示验证的结果。一般情况下验证函数只需要知道输入框的内容即可,可以通过 Entry 组件的 get() 方法获得该字符串。
下边的例子中,在第一个输入框输入“来自江南的你” 并通过 Tab 键将焦点转移到第二个输入框的时候,验证功能被成功触发:
import tkinter as tk
master = tk.Tk()
def test():
if e1.get() == "一只没有脚的猪":
print("正确!")
return True
else:
print("错误!")
e1.delete(0, "end")
return False
v = tk.StringVar()
#focusout 就是焦点离开时验证
e1 = tk.Entry(master, textvariable=v, validate="focusout", validatecommand=test)
e2 = tk.Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
当输入信息不是 “来自江南的你” 的时候,就会打印错误,然后清空输入框。
然后,invalidcommand 选项指定的函数只有在 validatecommand 的返回值为 False 的时候才被调用。
下边的例子中,在第一个输入框输入“来自江南的我”,并通过 Tab 键将焦点转移到第二个输入框,validatecommand 指定的验证函数被触发并返回 False,接着 invalidcommand 被触发:
import tkinter as tk
master = tk.Tk()
def test1():
if e1.get() == "一只没有脚的猪":
print("正确!")
return True
else:
print("错误!")
e1.delete(0, "end")
return False
def test2():
print("我被调用了......")
return True
v = tk.StringVar()
#focusout 就是焦点离开时验证
e1 = tk.Entry(master, textvariable=v, validate="focusout",validatecommand=test1,invalidcommand=test2)
e2 = tk.Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
最后,其实 Tkinter 还有隐藏技能,不过需要冷却才能触发
Tkinter 为验证函数提供一些额外的选项:
额外选项 | 含义 |
'%d' | 操作代码:0 表示删除操作;1 表示插入操作;2 表示获得、失去焦点或 textvariable 变量的值被修改 |
'%i' | 1. 当用户尝试插入或删除操作的时候,该选线表示插入或删除的位置(索引号) 2. 如果是由于获得、失去焦点或 textvariable 变量的值被修改而调用验证函数,那么该值是 -1 |
'%P' | 1. 当输入框的值允许改变的时候,该值有效 2. 该值为输入框的最新文本内容 |
'%s' | 该值为调用验证函数前输入框的文本内容 |
'%S' | 1. 当插入或删除操作触发验证函数的时候,该值有效 2. 该选项表示文本被插入和删除的内容 |
'%v' | 该组件当前的 validate 选项的值 |
'%V' | 1. 调用验证函数的原因 2. 该值是 'focusin','focusout','key' 或 'forced'(textvariable 选项指定的变量值被修改)中的一个 |
'%W' | 该组件的名字,不过是 tk 变量在内部注册的名字,为一串数字。 |
为了使用这些选项,你可以这样写:validatecommand=(f, s1, s2, ...)
其中,f 就是你“冷却后”的验证函数名,s1、s2、s3 这些是额外的选项,这些选项会作为参数依次传给 f 函数。我们刚刚说了,使用隐藏技能前需要冷却,其实就是调用 register() 方法将验证函数包装起来:
运行一下:
有了以上的内容,我们就可以来设计一个计算器了。
import tkinter as tk
master = tk.Tk()
frame = tk.Frame(master)
frame.pack(padx=10,pady=10)
v1 = tk.StringVar()
v2 = tk.StringVar()
v3 = tk.StringVar()
#针对输入框不能完全清空的问题,修改 test() 函数:
def test(content):
if content.isdigit() or content == "":
return True
else:
return False
#针对输入框为空时按下计算按钮会报错的问题,修改 calc() 函数:
def caculate():
if v1.get() == "" or v2.get() == "":
result = ""
v3.set(str(result))
else:
result = int(v1.get() )+ int(v2.get())
v3.set(str(result))
testCMD = frame.register(test) #冷却,就是调用 register() 方法将验证函数包装起来
e1 = tk.Entry(frame, textvariable=v1, width=10,validate="focusout", validatecommand=(testCMD, '%P'))
e1.grid(row=0,column=0)
lable1= tk.Label(frame,text='+')
lable1.grid(row=0,column=1)
e2 = tk.Entry(frame, textvariable=v2, width=10, validate="focusout", validatecommand=(testCMD, '%P'))
e2.grid(row=0,column=2)
lable1= tk.Label(frame,text='=')
lable1.grid(row=0,column=3)
e3 = tk.Entry(frame, textvariable=v3, width=10,state='readonly')
e3.grid(row=0,column=4)
button = tk.Button(frame,text='计算结果',command=caculate)
button.grid(row=1,column=2,pady=10)
frame.mainloop()
标签:10,067,Python,GUI,输入框,grid,tk,e1,frame 来源: https://blog.csdn.net/qq_38970783/article/details/88846384