Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)
个人博客转移至:https://sunhwee.com,第一时间会先发在前者,有时间再更新至博客园。
一、前言
二、Tkinter 是什么
三、Tkinter 控件详细介绍
1. Tkinter 模块元素简要说明
2. 常用窗口部件及简要说明:
四、动手实践学习
1. 创建主窗口及Label部件(标签)创建使用
2. Button窗口部件
3. Entry窗口部件
4. Text窗口部件
5. Listbox窗口部件
6. Radiobutton窗口部件
7. Checkbutton窗口部件
8. Scale窗口部件
9. Canvas窗口部件
10. Menu窗口部件
11. Frame 窗口部件
12. messageBox窗口部件
13. 窗口部件三种放置方式pack/grid/place
14. 综合练习,用户登录窗口例子
15. 其他部件后续再补充...
Python的标准Tk GUI工具包的接口。作为 python 特定的GUI界面,是一个图像的窗口,tkinter是python 自带的,可以编辑的GUI界面,我们可以用GUI 实现很多直观的功能,比如想开发一个计算器,如果只是一个程序输入,输出窗口的话,是没用用户体验的。所有开发一个图像化的小窗口,就是必要的。
对于稍有GUI编程经验的人来说,Python的Tkinter界面库是非常简单的。python的GUI库非常多,选择Tkinter,一是最为简单,二是自带库,不需下载安装,随时使用,三则是从需求出发,Python作为一种脚本语言,一种胶水语言,一般不会用它来开发复杂的桌面应用,它并不具备这方面的优势,使用Python,可以把它作为一个灵活的工具,而不是作为主要开发语言,那么在工作中,需要制作一个小工具,肯定是需要有界面的,不仅自己用,也能分享别人使用,在这种需求下,Tkinter是足够胜任的!
这篇文章主要做一个简单概述和实践编程,对于从没有接触过GUI的新手,在脑中树立一个基本的界面编程概念,同时自己也能学会如何简单的实现一些小的图形窗口功能。
对于Tkinter编程,可以用两个比喻来理解:
- 第一个,作画。我们都见过美术生写生的情景,先支一个画架,放上画板,蒙上画布,构思内容,用铅笔画草图,组织结构和比例,调色板调色,最后画笔勾勒。相应的,对应到tkinter编程,那么我们的显示屏就是支起来的画架,根窗体就是画板,在tkinter中则是Toplevel,画布就是tkinter中的容器(Frame),画板上可以放很多张画布(Convas),tkinter中的容器中也可以放很多个容器,绘画中的构图布局则是tkinter中的布局管理器(几何管理器),绘画的内容就是tkinter中的一个个小组件,一幅画由许多元素构成,而我们的GUI界面,就是有一个个组件拼装起来的,它们就是widget。
- 第二个,我们小时候都玩过积木,只要发挥创意,相同的积木可以堆出各种造型。tkinter的组件也可以看做一个个积木,形状或许不同,其本质都是一样的,就是一个积木,不管它长什么样子,它始终就是积木!所以这些小组件都有许多共性,另外,个人认为,学习界面编程,最重要的不是一开始学习每个积木的样子,不是学习每个组件怎么用,而是这些组件该怎么放。初始学习中,怎么放远远比怎么用重要的多。网上有大量的文章资料,基本全是介绍组件怎么用的,对于怎么放,也就是tkinter中的布局管理器,都是一笔带过,这对初学者有点本末倒置,或许绝大部分是转载的原因吧,极少是自己真正写的。组件怎么用不是最迫切的,用到的时候再去了解也不迟,边用边学反而更好。因此我将专门写一章,详细介绍布局管理器的使用。
The Button Widget
The Canvas Widget
The Checkbutton Widget
The Entry Widget
The Frame Widget
The Label Widget
The LabelFrame Widget
The Listbox Widget
The Menu Widget
The Menubutton Widget
The Message Widget
The OptionMenu Widget
The PanedWindow Widget
The Radiobutton Widget
The Scale Widget
The Scrollbar Widget
The Spinbox Widget
The Text Widget
The Toplevel Widget
Basic Widget Methods
Toplevel Window Methods
The Grid Geometry Manager
The Pack Geometry Manager
The Place Geometry Manager
The Pack Geometry Manager
The Place Geometry Manager
1. Grid:The Grid Geometry Manager
grid 是方格, 所以所有的内容会被放在这些规律的方格中。例如:
for i in range(3): for j in range(3): tk.Label(window, text=1).grid(row=i, column=j, padx=10, pady=10, ipadx=10, ipady=10)
以上的代码就是创建一个三行三列的表格,其实 grid 就是用表格的形式定位的。这里的参数 row 为行,colum 为列,padx 就是单元格左右间距,pady 就是单元格上下间距,ipadx是单元格内部元素与单元格的左右间距,ipady是单元格内部元素与单元格的上下间距。
示例代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- # author:洪卫 import tkinter as tk # 使用Tkinter前需要先导入 # 第1步,实例化object,建立窗口window window = tk.Tk() # 第2步,给窗口的可视化起名字 window.title('My Window') # 第3步,设定窗口的大小(长 * 宽) window.geometry('500x300') # 这里的乘是小x # 第4步,grid 放置方法 for i in range(3): for j in range(3): tk.Label(window, text=1).grid(row=i, column=j, padx=10, pady=10, ipadx=10, ipady=10) # 第5步,主窗口循环显示 window.mainloop()
测试效果:
2. Pack:The Pack Geometry Manager
我们常用的pack(), 他会按照上下左右的方式排列.例如:
tk.Label(window, text='P', fg='red').pack(side='top') # 上 tk.Label(window, text='P', fg='red').pack(side='bottom') # 下 tk.Label(window, text='P', fg='red').pack(side='left') # 左 tk.Label(window, text='P', fg='red').pack(side='right') # 右
示例代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- # author:洪卫 import tkinter as tk # 使用Tkinter前需要先导入 # 第1步,实例化object,建立窗口window window = tk.Tk() # 第2步,给窗口的可视化起名字 window.title('My Window') # 第3步,设定窗口的大小(长 * 宽) window.geometry('500x300') # 这里的乘是小x # 第4步,pack 放置方法 tk.Label(window, text='P', fg='red').pack(side='top') # 上 tk.Label(window, text='P', fg='red').pack(side='bottom') # 下 tk.Label(window, text='P', fg='red').pack(side='left') # 左 tk.Label(window, text='P', fg='red').pack(side='right') # 右 # 第5步,主窗口循环显示 window.mainloop()
测试效果:
3. Place:The Place Geometry Manager
再接下来我们来看place(), 这个比较容易理解,就是给精确的坐标来定位,如此处给的(50, 100),就是将这个部件放在坐标为(x=50, y=100)的这个位置, 后面的参数 anchor='nw',就是前面所讲的锚定点是西北角。例如:
tk.Label(window, text='Pl', font=('Arial', 20), ).place(x=50, y=100, anchor='nw')
示例代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- # author:洪卫 import tkinter as tk # 使用Tkinter前需要先导入 # 第1步,实例化object,建立窗口window window = tk.Tk() # 第2步,给窗口的可视化起名字 window.title('My Window') # 第3步,设定窗口的大小(长 * 宽) window.geometry('500x300') # 这里的乘是小x # 第4步,place 放置方法(精准的放置到指定坐标点的位置上) tk.Label(window, text='Pl', font=('Arial', 20), ).place(x=50, y=100, anchor='nw') # 第5步,主窗口循环显示 window.mainloop()
测试效果:
14. 综合练习,用户登录窗口例子
编写一个用户登录界面,用户可以登录账户信息,如果账户已经存在,可以直接登录,登录名或者登录密码输入错误会提示,如果账户不存在,提示用户注册,点击注册进去注册页面,输入注册信息,确定后便可以返回登录界面进行登录。
示例代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- # author:洪卫 import tkinter as tk # 使用Tkinter前需要先导入 import tkinter.messagebox import pickle # 第1步,实例化object,建立窗口window window = tk.Tk() # 第2步,给窗口的可视化起名字 window.title('Wellcome to Hongwei Website') # 第3步,设定窗口的大小(长 * 宽) window.geometry('400x300') # 这里的乘是小x # 第4步,加载 wellcome image canvas = tk.Canvas(window, width=400, height=135, bg='green') image_file = tk.PhotoImage(file='pic.gif') image = canvas.create_image(200, 0, anchor='n', image=image_file) canvas.pack(side='top') tk.Label(window, text='Wellcome',font=('Arial', 16)).pack() # 第5步,用户信息 tk.Label(window, text='User name:', font=('Arial', 14)).place(x=10, y=170) tk.Label(window, text='Password:', font=('Arial', 14)).place(x=10, y=210) # 第6步,用户登录输入框entry # 用户名 var_usr_name = tk.StringVar() var_usr_name.set('example@python.com') entry_usr_name = tk.Entry(window, textvariable=var_usr_name, font=('Arial', 14)) entry_usr_name.place(x=120,y=175) # 用户密码 var_usr_pwd = tk.StringVar() entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, font=('Arial', 14), show='*') entry_usr_pwd.place(x=120,y=215) # 第8步,定义用户登录功能 def usr_login(): # 这两行代码就是获取用户输入的usr_name和usr_pwd usr_name = var_usr_name.get() usr_pwd = var_usr_pwd.get() # 这里设置异常捕获,当我们第一次访问用户信息文件时是不存在的,所以这里设置异常捕获。 # 中间的两行就是我们的匹配,即程序将输入的信息和文件中的信息匹配。 try: with open('usrs_info.pickle', 'rb') as usr_file: usrs_info = pickle.load(usr_file) except FileNotFoundError: # 这里就是我们在没有读取到`usr_file`的时候,程序会创建一个`usr_file`这个文件,并将管理员 # 的用户和密码写入,即用户名为`admin`密码为`admin`。 with open('usrs_info.pickle', 'wb') as usr_file: usrs_info = {'admin': 'admin'} pickle.dump(usrs_info, usr_file) usr_file.close() # 必须先关闭,否则pickle.load()会出现EOFError: Ran out of input # 如果用户名和密码与文件中的匹配成功,则会登录成功,并跳出弹窗how are you? 加上你的用户名。 if usr_name in usrs_info: if usr_pwd == usrs_info[usr_name]: tkinter.messagebox.showinfo(title='Welcome', message='How are you? ' + usr_name) # 如果用户名匹配成功,而密码输入错误,则会弹出'Error, your password is wrong, try again.' else: tkinter.messagebox.showerror(message='Error, your password is wrong, try again.') else: # 如果发现用户名不存在 is_sign_up = tkinter.messagebox.askyesno('Welcome! ', 'You have not sign up yet. Sign up now?') # 提示需不需要注册新用户 if is_sign_up: usr_sign_up() # 第9步,定义用户注册功能 def usr_sign_up(): def sign_to_Hongwei_Website(): # 以下三行就是获取我们注册时所输入的信息 np = new_pwd.get() npf = new_pwd_confirm.get() nn = new_name.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: tkinter.messagebox.showerror('Error', 'Password and confirm password must be the same!') # 如果用户名已经在我们的数据文件中,则提示Error, The user has already signed up! elif nn in exist_usr_info: tkinter.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) tkinter.messagebox.showinfo('Welcome', 'You have successfully signed up!') # 然后销毁窗口。 window_sign_up.destroy() # 定义长在窗口上的窗口 window_sign_up = tk.Toplevel(window) window_sign_up.geometry('300x200') 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=130, 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=130, 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=130, y=90) # 下面的 sign_to_Hongwei_Website btn_comfirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Hongwei_Website) btn_comfirm_sign_up.place(x=180, y=120) # 第7步,login and sign up 按钮 btn_login = tk.Button(window, text='Login', command=usr_login) btn_login.place(x=120, y=240) btn_sign_up = tk.Button(window, text='Sign up', command=usr_sign_up) btn_sign_up.place(x=200, y=240) # 第10步,主窗口循环显示 window.mainloop()
测试效果:
15. 其他部件后续再补充...
注:不同电脑可能配置环境略有不同,如有小错误可以自己调试一下。