如下是学习笔记,学习资源来自
莫烦python:https://morvanzhou.github.io/tutorials/python-basic/tkinter/
blibli对应视频:https://www.bilibili.com/video/av16942112?zw
更多关于 python 的文章可以参考 【Python】
文章目录
1 什么是 Tkinter
Tkinter 是使用 python 进行窗口视窗设计的模块. 简单的构造, 多平台, 多系统的兼容性, 能让它成为让你快速入门定制窗口文件的好助手. 它在 python 窗口视窗模块中是一款简单型的. 所以用来入门, 熟悉 窗口视窗的使用, 非常有必要.
2 Label & Button 标签和按钮
1)label
import tkinter as tk
# 窗口 object
window = tk.Tk()
window.title('windows')
window.geometry('300x100')
# label
l = tk.Label(window, text = 'My name is Bryant',bg='green',fg='white',
font=('Arial',12),width=15,height=2,)
l.pack() # 固定窗口位置
window.mainloop()
bg
、fg
控制颜色,最后执行 window.mainloop
不断刷新
2)button
实现点一下显示 ‘you hit me’ 再点一下不显示的功能
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('300x100')
var = tk.StringVar()
on_hit = False
def hit_me():
global on_hit
if on_hit == False:
on_hit = True
var.set('you hit me')
else:
on_hit = False
var.set('')
# label,使用 textvariable 替换 text, 因为这个可以变化
l = tk.Label(window, textvariable = var,bg='green',fg='white',
font=('Arial',12),width=15,height=2,)
l.pack()
# button
b = tk.Button(window,text='hit me',width=15,height=2,
command=hit_me)
b.pack()
window.mainloop()
command=hit_me
为点击按钮式执行的命令,具体功能可以在 hit_me
函数中 DIY
点一下
再点一下
3 Entry & Text 输入,文本框
通过insert_point
和 insert_end
按钮,实现将 entry
中输入内容插入到 text
中的功能,insert_point
按钮将输入内容插入到光标后, insert_end
插入在文本末尾!
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('300x200')
var = tk.StringVar()
# entry
e = tk.Entry(window,show=None)
e.pack()
# button
# 在光标处插入
def insert_point():
var = e.get()
t.insert('insert',var)
# 在末尾处插入
def insert_end():
var = e.get()
t.insert('end',var)
b1 = tk.Button(window,text='insert point',width=15,height=2,
command=insert_point)
b1.pack()
b2 = tk.Button(window,text='insert end',width=15,height=2,
command=insert_end)
b2.pack()
# text
t = tk.Text(window,height=2) # 两行
t.pack()
window.mainloop()
输入Bryant
点击 insert point
按钮后的结果
输入 111
,将光标移动到 text
框中 y
字母后,点击insert point
和 insert end
的结果
当然也可以比较灵活的设置,比如指定在某行某列插入,下例子为在第一行,第一列后插入 entry 的值
def insert_end():
var = e.get()
#t.insert('end',var)
t.insert(1.1,var)
我们登录的时候密码往往为 *
,这里可以通过 tk.Entry(window,show=None)
中 show
参数来设定,比如show = ‘*’
,当然也可以 DIY 成任意的 char
4 Listbox 列表部件
实现 listbox
,选择 listbox
中一项,点击print selection
按钮,在 label 中显示所选中的项
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('200x300')
var1 = tk.StringVar() # for label
var2 = tk.StringVar() # for listbox
var2.set((11,22,33,44))
# label
l = tk.Label(window,bg='yellow',width=4,textvariable=var1)
# listbox
lb = tk.Listbox(window,listvariable=var2)
# 往 listbox 中添加项,法一
list_iterms = [1,2,3,4]
for i in list_iterms:
lb.insert('end',i)
# 往 listbox 中添加项,法二
lb.insert(1,'fisrt')
lb.insert(2,'second')
# 删除 listbox 中的项
lb.delete(2)
# button
def print_select():
value = lb.get(lb.curselection())
var1.set(value)
b = tk.Button(window,text='print selection',width=15,height=1,
command=print_select)
l.pack() # label
b.pack() # button
lb.pack()# listbox
window.mainloop()
5 Radiobutton 选择按钮
只能选择一个
实现 Radiobutton
,选择某一个选项,在 label
中显示选择了哪个选项,默认为 empty
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('250x100')
var = tk.StringVar()
# label
l = tk.Label(window,bg='yellow',width=16,text='empty')
l.pack()
# radiobutton
def print_selection():
l.config(text='you have selected ' + var.get()) # 改变label中的 text属性
# 选中 Option A 的时候 变量 var 被赋值为 A
r1 = tk.Radiobutton(window,text='Option A',variable=var,value='A',
command=print_selection)
r1.pack()
# 选中 Option B 的时候 变量 var 被赋值为 B
r2 = tk.Radiobutton(window,text='Option B',variable=var,value='B',
command=print_selection)
r2.pack()
# 选中 Option C 的时候 变量 var 被赋值为 C
r3 = tk.Radiobutton(window,text='Option C',variable=var,value='C',
command=print_selection)
r3.pack()
window.mainloop()
6 Scale 尺度
实现 scale
,左右滑动,数值显示在 label
中
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('250x100')
# label
l = tk.Label(window,bg='yellow',width=20,text='empty')
l.pack()
# scale
def print_selection(v):
l.config(text='you have selected ' + v) # 改变label中的 text属性
s = tk.Scale(window,label='try me', from_=5,to=11,orient=tk.HORIZONTAL,
length=200,showvalue=0,tickinterval=3,resolution=0.01,command=print_selection)
s.pack()
window.mainloop()
注意 print_selection(v)
的形参 v
from_=5,to=11
是从5到11orient=tk.HORIZONTAL
是设置滚动条的方向,还有VERTICAL
length
指滚动条部件的长度,但注意的是和其他部件width
表示不同,width表示的是以字符为单位,比如width=4,就是4个字符的长度,而此处的length=200,是指我们常用的像素为单位,即长度为200个像素tickinterval
是坐标的间隔,tickinterval=2
,显示的即为效果图中的5.00 7.00 9.00 11.00
如果tickinterval=3
则为5.00 8.00 11.00
resolution=0.01
保留2位小数,还有例如0.1
showvalue
就是设置在滚动条上方的显示。showvalue=0
显示的就是效果图,上方无结果显示,如果改为showvalue=1
,则会显示为:
我们用 label 实时显示出了输出,所以没有必要设置showvalue=1
7 Checkbutton 勾选项
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('250x100')
var1 = tk.IntVar()
var2 = tk.IntVar()
# label
l = tk.Label(window,bg='yellow',width=20,text='empty')
l.pack()
# checkbutton
def print_selection():
if var1.get()==1 and var2.get()==0:
l.config(text='I love only Python')
elif var1.get()==0 and var2.get()==1:
l.config(text='I love only C++')
elif var1.get()==0 and var2.get()==0:
l.config(text='I do not love either')
else:
l.config(text='I love both')
c1 = tk.Checkbutton(window,text='python',variable=var1,onvalue=1,offvalue=0,
command=print_selection)
c2 = tk.Checkbutton(window,text='c++',variable=var2,onvalue=1,offvalue=0,
command=print_selection)
c1.pack()
c2.pack()
window.mainloop()
参数onvalue
和前面讲的部件radiobutton
中的value相似, 当我们选中了这个checkbutton
,onvalue
的值1就会放入到var1
中, 然后var1
将其赋值给参数variable
,offvalue
用法相似,但是offvalue
是在没有选中这个checkbutton
时,offvalue
的值1放入var1
,然后赋值给参数variable 这是创建一个checkbutton
部件,以此类推,可以创建多个checkbutton
8 Canvas 画布
先画一个背景,然后上一张图,画直线,画圆,画正方形,画扇形,实现点击 move 移动某个图形的功能。
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('300x300')
# canvas
canvas = tk.Canvas(window,bg='blue',height=250,width=300) # 画布
image_file = tk.PhotoImage(file='C://Users/13663/Desktop/1.png') # 载入图片
image=canvas.create_image(0,0,anchor='nw',image=image_file) # 把图片放在画布上
line = canvas.create_line(0,125,125,250)# 直线
oval = canvas.create_oval(125,0,250,125,fill='red') # 圆形
arc = canvas.create_arc(125,125,250,250,start=0,extent=180)# 扇形
rect = canvas.create_rectangle(125,125,125+30,125+30)
canvas.pack()
# button
def move():
canvas.move(rect,20,20)
b = tk.Button(window,text='move',command=move).pack()
window.mainloop()
坐标都是 (x0,y0,x1,y1)
,左上右下,move
按钮功能对任何图形都有效,改变 move()
中的参数就行!
注意 canvas.create_image
中的 anchor
属性,有如下9种形式,注意要小写,表示把图片对应的区域放置在画布(0,0)
处,也就画布的左上角处!
移动圆玩玩,canvas.move(oval,20,20)
,20,20表示每次 x 和 y 移动的像素值
9 Menubar 菜单
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('300x300')
# label
l = tk.Label(window,text='',bg='yellow')
l.pack()
counter = 0
# menubar
def do_job():
global counter
l.config(text='do'+ str(counter))
counter+=1
def quit():
window.quit()
window.destroy()
exit()
## 创建一个菜单栏,这里我们可以把他理解成一个容器,在窗口的上方
menubar = tk.Menu(window)
## 定义一个空菜单单元
filemenu = tk.Menu(menubar,tearoff=0)
##将上面定义的空菜单命名为`File`,放在菜单栏中,就是装入那个容器中
menubar.add_cascade(label='File',menu=filemenu)
##在`File`中加入`New`的小菜单,即我们平时看到的下拉菜单,每一个小菜单对应命令操作。
##如果点击这些单元, 就会触发`do_job`的功能
filemenu.add_command(label='New',command=do_job)
filemenu.add_command(label='Open',command=do_job)##同样的在`File`中加入`Open`小菜单
filemenu.add_command(label='Save',command=do_job)##同样的在`File`中加入`Save`小菜单
filemenu.add_separator()# 分割线
filemenu.add_command(label='Exit',command=quit)
## 子菜单
submenu = tk.Menu(filemenu,tearoff=0)##和上面定义菜单一样,不过此处实在`File`上创建一个空的菜单
filemenu.add_cascade(label='Import', menu=submenu, underline=0)##给放入的菜单`submenu`命名为`Import`
submenu.add_command(label="Submenu1", command=do_job)##这里和上面也一样,在`Import`中加入一个小菜单命令`Submenu1`
## Edit
editmenu = tk.Menu(menubar,tearoff=0)
menubar.add_cascade(label='Edit',menu=editmenu)
editmenu.add_command(label='Cut',command=do_job)
editmenu.add_command(label='Copy',command=do_job)
editmenu.add_command(label='Paste',command=do_job)
window.config(menu=menubar)
window.mainloop()
点其它任何菜单功能实现,计数功能, 点 exit 退出 窗口(截图失败,用原作者的图感受下吧 https://morvanzhou.github.io/tutorials/python-basic/tkinter/2-08-menubar/)
10 Frame 框架
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('my window')
window.geometry('200x150')
tk.Label(window,text='on the window').pack()
frm = tk.Frame(window) #在`window`上创建一个`frame`
frm.pack()
###在刚刚创建的`frame`上创建两个`frame`,我们可以把它理解成一个大容器里套了一个小容器,
frm_l = tk.Frame(frm)
frm_r = tk.Frame(frm)
###这里是控制小的`frm`部件在大的`frm`的相对位置,此处`frm_l`就是在`frm`的左边,`frm_r`在`frm`的右边
frm_l.pack(side='left')
frm_r.pack(side='right')
tk.Label(frm_l,text='on the frm_l1').pack()
tk.Label(frm_l,text='on the frm_l2').pack()
tk.Label(frm_r,text='on the frm_l1').pack()
window.mainloop()
11 messagebox 弹窗
点击按钮,弹出不同的提示框
import tkinter as tk
import tkinter.messagebox
window = tk.Tk() # 窗口 object
window.title('demo')
window.geometry('250x100')
def hit_me():
#tk.messagebox.showinfo(title='Hi',message='hahaha')
tk.messagebox.showwarning(title='Hi',message='nonono')
#tk.messagebox.showerror(title='Hi',message='No!never')
#print(tk.messagebox.askquestion(title='Hi',message='No!never')) # return yes or no
#print(tk.messagebox.askyesno(title='Hi',message='No!never')) # return yT or F
#print(tk.messagebox.askretrycancel(title='Hi',message='No!never')) # return T or F
#print(tk.messagebox.askokcancel(title='Hi',message='No!never')) # return T or F
tk.Button(window,text='hit me',command=hit_me).pack()
window.mainloop()
例如
12 pack grid place 放置位置
1)pack
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('demo')
window.geometry('200x200')
# pack
tk.Label(window,text=1).pack(side='top')
tk.Label(window,text=1).pack(side='bottom')
tk.Label(window,text=1).pack(side='left')
tk.Label(window,text=1).pack(side='right')
window.mainloop()
2)grid
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('demo')
window.geometry('200x200')
# grid
for i in range(4):
for j in range(3):
tk.Label(window,text=1).grid(row=i,column=j,padx=10,pady=10)
window.mainloop()
其中 padx
和 pady
是增加间距
3)place
指定放在某个像素值
import tkinter as tk
window = tk.Tk() # 窗口 object
window.title('demo')
window.geometry('200x200')
tk.Label(window,text=1).place(x=10,y=100,anchor='nw')
window.mainloop()
13 登录窗口(大杂烩 ★★★★★)
脸我遮住了, 哈哈,将前面的知识点汇总,实现一个登录页面的功能。涉及到:canvas、label、entry、button、messagebox、pack、place
1)管理员
帐号 Bryant
密码 Bryant
2)登录成功
3)密码错误
4)帐号错误
5)注册
点击 4)中的 是
或者主页面的 sign up
按钮
6)注册成功
7)代码实现
import tkinter as tk
import pickle
window = tk.Tk() # 窗口 object
window.title('Welcome to Bryant Python')
window.geometry('600x400')
### welcome image (canvas)
canvas = tk.Canvas(window,height=300,width=600)
image_file = tk.PhotoImage(file = 'C://Users/13663/Desktop/1.png')
image = canvas.create_image(0,0,anchor='nw',image=image_file)
canvas.pack(side='top')
### variable define
var_usr_name = tk.StringVar()
var_usr_name.set('example@python.com')
var_usr_password = tk.StringVar()
### login and sign up (button function)
def usr_login():
usr_name = var_usr_name.get()
usr_pwd = var_usr_password.get()
try:
with open('usrs_info.pickle','rb') as usr_file:
usrs_info = pickle.load(usr_file)
except FileNotFoundError:
with open('usrs_info.pickle','wb') as usr_file:
usrs_info = {'Bryant':'Bryant'}
pickle.dump(usrs_info,usr_file)
#如果用户名和密码与文件中的匹配成功,则会登录成功,并跳出弹窗`how are you?`加上你的用户名。
if usr_name in usrs_info:
if usr_pwd == usrs_info[usr_name]:
tk.messagebox.showinfo(title='Welcome', message='How are you? ' + usr_name)
##如果用户名匹配成功,而密码输入错误,则会弹出'Error, your password is wrong, try again.'
else:
tk.messagebox.showerror(message='Error, your password is wrong, try again.')
else: # 如果发现用户名不存在
is_sign_up = tk.messagebox.askyesno('Welcome',
'You have not sign up yet. Sign up today?')
# 提示需不需要注册新用户
if is_sign_up:
usr_sign_up()
def usr_sign_up():
def sign_to_Bryant_Python():
##以下三行就是获取我们注册时所输入的信息
nn = new_name.get()
np = new_pwd.get()
npf = new_pwd_confirm.get()
##这里是打开我们记录数据的文件,将注册信息读出
with open('usrs_info.pickle', 'rb') as usr_file:
exist_usr_info = pickle.load(usr_file)
##这里就是判断,如果两次密码输入不一致,则提示`'Error', 'Password and confirm password must be the same!'`
if np != npf:
tk.messagebox.showerror('Error', 'Password and confirm password must be the same!')
##如果用户名已经在我们的数据文件中,则提示`'Error', 'The user has already signed up!'`
elif nn in exist_usr_info:
tk.messagebox.showerror('Error', 'The user has already signed up!')
##最后如果输入无以上错误,则将注册输入的信息记录到文件当中,并提示注册成功`'Welcome', 'You have successfully signed up!'`
##然后销毁窗口。
else:
exist_usr_info[nn] = np
with open('usrs_info.pickle', 'wb') as usr_file:
pickle.dump(exist_usr_info, usr_file)
tk.messagebox.showinfo('Welcome', 'You have successfully signed up!')
##然后销毁窗口。
window_sign_up.destroy()
### window when sign up
window_sign_up = tk.Toplevel(window)
window_sign_up.geometry('350x200')
window_sign_up.title('Sign up window')
### 用户名
new_name = tk.StringVar()#将输入的注册名赋值给变量
new_name.set('example@python.com')#将最初显示定为'example@python.com'
tk.Label(window_sign_up, text='User name: ').place(x=10, y= 10)#将`User name:`放置在坐标(10,10)。
entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)#创建一个注册名的`entry`,变量为`new_name`
entry_new_name.place(x=150, y=10)#`entry`放置在坐标(150,10).
### 密码
new_pwd = tk.StringVar()
tk.Label(window_sign_up, text='Password: ').place(x=10, y=50)
entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
entry_usr_pwd.place(x=150, y=50)
### 确认密码
new_pwd_confirm = tk.StringVar()
tk.Label(window_sign_up, text='Confirm password: ').place(x=10, y= 90)
entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
entry_usr_pwd_confirm.place(x=150, y=90)
# 下面的 sign_to_Bryant_Python 我们再后面接着说
btn_comfirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Bryant_Python)
btn_comfirm_sign_up.place(x=150, y=130)
### use information (entry)
tk.Label(window,text='User name:').place(x=150,y=250)
tk.Label(window,text='Password:').place(x=150,y=290)
### usrname entry
entry_usr_name = tk.Entry(window,textvariable=var_usr_name)
entry_usr_name.place(x=260,y=250)
### password entry
entry_usr_pwd = tk.Entry(window,textvariable=var_usr_password,show='*')
entry_usr_pwd.place(x=260,y=290)
### login button
bt_login = tk.Button(window,text='Login',command=usr_login)
bt_login.place(x=270,y=330)
### signup button
bt_sign_up = tk.Button(window,text='Sign up',command=usr_sign_up)
bt_sign_up.place(x=350,y=330)
window.mainloop()
更多关于 python 的文章可以参考 【Python】