Python:GUI库tkinter(三)
这一章是对前两章的总结:
前两章是对控件的介绍,第一章可以知道各控件使用时的具体参数,第二章以具体的例子展示了每个控件的用法,本章将所有控件放在一起,看看构建一个GUI的一般方法与语句。
以这可能是最好玩的python GUI入门实例! - 简书和Python:GUI库tkinter(二)中的例子为例,给出制作一个具有注册登录功能的界面的一般流程:
from tkinter import *
from tkinter import messagebox ①
import pickle window=Tk()
window.title('My Window') ②
window.geometry('500x300') #主窗口设置 #图片:Canvas ③
canvas=Canvas(window,width=400,height=135,bg='green')
image_file=PhotoImage(file='Squirrel.png')
canvas.create_image(200,0,anchor='n',image=image_file)
canvas.pack(side='top') #文本:Label ④
Label(window,text='Welcome',font=('Arial',16)).pack()
#输入框前的文本:用户和密码
Label(window,text='Username',font=('Arial',14)).place(x=10,y=170)
Label(window,text='Password',font=('Arial',14)).place(x=10,y=210) #输入框中的初始字:StringVar
var_username=StringVar() ⑤
var_username.set('example@python.com')#设置初值
#输入框:Entry,通过构造时的参数textvariable显示之前的初始字
#用户名输入框 ⑥
entry_username=Entry(window,textvariable=var_username,font=('Arial',14))#这里的font是输入时显示的字体
entry_username.place(x=120,y=175)
#密码输入框
entry_password=Entry(window,font=('Arial',14),show='*')
entry_password.place(x=120,y=215) #用户登录功能函数 ⑦
def usr_login():
...
#用户注册功能函数
def usr_sign_up():
... #登录与注册按钮,关联函数 ⑧
btn_login=Button(window,text='Login',command=usr_login)
btn_login.place(x=120,y=240)
btn_sign_up=Button(window,text='sign_up',command=usr_sign_up)
btn_sign_up.place(x=200,y=240) #运行主框架 ⑨
window.mainloop()
各部分解释说明
①
from tkinter import *
from tkinter import messagebox
import pickle
导入各种库,令笔者不解的是,虽然已经import *,但是如果要用到消息框,仍然需要再import messagebox,而不能直接用messagebox,具体原因未知。
pickle库则是,如果想将某些数据以序列化二进制数的形式保存到某个文本文件中(或从这些文件中提取序列化后的文本文件),就需要用到这个库,具体用法详见序列化 pickle JSON - ShineLe - 博客园
由于是登录界面模拟,所以自然要保存许多用户的信息,要用到EXCEL或者数据库,这时候也可以用pandas库进行写入或读取数据,具体用法见Python:pandas(一)——常用、读写函数read_csv、read_excel、to_csv - ShineLe - 博客园
②
window=Tk()
window.title('My Window') ②
window.geometry('500x300') #主窗口设置
主框架(Tk类)构建最常用的三句话,所谓主框架就是最终显示的GUI所在的窗口。
这三句话的功能为:窗口实例化、窗口标题、窗口尺寸
③
#图片:Canvas ③
canvas=Canvas(window,width=400,height=135,bg='green')
image_file=PhotoImage(file='Squirrel.png')
canvas.create_image(200,0,anchor='n',image=image_file)
canvas.pack(side='top')
这一段话的目的是,加载一个图片到窗口内,需要用到Canvas控件,把图片显示到Canvas上,再把Canvas部署到主框架下。
canvas=Canvas(window,width=400,height=135,bg='green') 创建承接图片的Canvas控件:
image_file=PhotoImage(file='Squirrel.png') 创建一副图片对象
canvas.create_image(200,0,anchor='n',image=image_file) 使用create_image方法在Canvas上显示图片
canvas.pack(side='top') 部署Canvas
就像QQ登录界面中有一个企鹅图片一样,这里也可以在你的GUI初始界面中布置一个你自己的图片。
④
#各种文本
Label(window,text='Welcome',font=('Arial',16)).pack()
Label(window,text='Username:',font=('Arial',14)).place(x=10,y=170)
Label(window,text='Password:',font=('Arial',14)).place(x=10,y=210)
这三行是文本,第一行是紧贴着图片下的一个常见的介绍文本。第二行和第三行的文本分别部署在Username和Password输入框之前,可以让用户知道这个输入框是干什么用的。
⑤、⑥
#用户输入框
var_usr_name=StringVar()
var_usr_name.set('example@python.com')
entry_usr_name=Entry(window,textvariable=var_usr_name,font=('Arial',14))
entry_usr_name.place(x=120,y=175)
#密码输入框
var_usr_pwd=StringVar()
entry_usr_pwd=Entry(window,textvariable=var_usr_pwd,font=('Arial',14),show='*')
entry_usr_pwd.place(x=120,y=215)
两个输入框,分别是用户名和密码。
如果想要在第一次打开界面时在输入框内显示默认的字符时,就要用到textvariable参数,该参数承接一个StringVar变量,这种变量要想设置或者获取值,需要用到方法get与set,而不能简单地用赋值号。
※※另外,关于textvariable需要补充的是,不论是否显示输入框中的默认值,都要设置这个参数,因为这个参数接收了输入框中输入的数值,不设置这个参数的话,输入到输入框中的值就不会保存下来。在以后要用到输入值的时候,通过StringVar类的get、set方法进行。
最后,如果不想明文显示输入的内容(比如输入的密码),可以通过设置show参数实现。
⑦
def usr_login():
#下边两行代码就是获取用户输入的username和password
usr_name=var_usr_name.get() (1)
usr_pwd=var_usr_pwd.get() #设置异常捕获,当我们第一次访问用户信息文件时是不存在的,所以之而立设置异常捕获
try:
with open('usrs_info.pickle','rb') as usr_file: (2)
usrs_info=pickle.load(usr_file)
except FileNotFoundError:
#这里是当我们没有读取到usr_file时候,程序会创建一个usr_file的文件
#并且将管理员的用户和密码输入,即用户名和密码均为'admin'
with open('usrs_info.pickle','wb')as usr_file: (3)
usrs_info={'admin':'admin'}
pickle.dump(usrs_info,usr_file)
if usr_name in usrs_info:
if usr_pwd == usrs_info[usr_name]: (4)
messagebox.showinfo(title='Welcome',message='How are you? '+usr_name)
else:
messagebox.showerror(message='Error,your password is wrond,try again.')
else: (5)
is_sign_up=messagebox.askyesno('Welcome!','You have not signed up yet. Sign up please!')
if is_sign_up:
usr_sign_up() def usr_sign_up():
def sign_to_Le_Website(): (6)
#以下三行就是获取我们注册时候输入的信息
np=new_pwd.get() (7)
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) (8)
#判断两次密码是否输入一致
if np!=npf: (9)
messagebox.showerror('Error','Password and confirm password must be the same')
#如果用户名已经在我们的数据文件中,则提示Error,用户已注册
elif nn in exist_usr_info:
messagebox.showerror('Error','The user has already signed up!')
#输入正确时
else:
exist_usr_info[nn]=np (10)
with open('usrs_info.pickle','wb') as usr_file:
pickle.dump(exist_usr_info,usr_file)
messagebox.showinfo('Welcome','You have successfully signed up!')
window_sign_up.destroy() (11) window_sign_up=Toplevel(window) (12)
window_sign_up.geometry('300x200')
window_sign_up.title('Sign up window') new_name=StringVar()
new_name.set('example@python.com')
Label(window_sign_up,text='Username:').place(x=10,y=10)
entry_new_name=Entry(window_sign_up,textvariable=new_name)
entry_new_name.place(x=130,y=10) new_pwd=StringVar() (13)
Label(window_sign_up,text='Password:').place(x=10,y=50)
entry_usr_pwd_confirm=Entry(window_sign_up,textvariable=new_pwd,show='*')
entry_usr_pwd_confirm.place(x=130,y=50) new_pwd_confirm=StringVar()
Label(window_sign_up,text='Confirm Password:').place(x=10,y=90)
entry_usr_pwd_confirm=Entry(window_sign_up,textvariable=new_pwd_confirm,show='*')
entry_usr_pwd_confirm.place(x=130,y=90) btn_confirm_sign_up=Button(window_sign_up,text='Sign up',command=sign_to_Le_Website)
btn_confirm_sign_up.place(x=180,y=120) (14)
这一部分是功能函数的实现,包括登录和注册功能。这两项也是下边⑨部分设置的两个按钮的响应函数。由于这一部分函数内容涉及较多,依旧拆分为小块说明。
(1)
usr_name=var_usr_name.get()
usr_pwd=var_usr_pwd.get()
var_usr_name、var_usr_pwd分别是⑥中设置的用来承接输入框输入值的两个变量,在创建Entry时通过参数textvariable说明
(2)、(3)
#设置异常捕获,当我们第一次访问用户信息文件时是不存在的,所以之而立设置异常捕获
try:
with open('usrs_info.pickle','rb') as usr_file: (2)
usrs_info=pickle.load(usr_file)
except FileNotFoundError:
#这里是当我们没有读取到usr_file时候,程序会创建一个usr_file的文件
#并且将管理员的用户和密码输入,即用户名和密码均为'admin'
with open('usrs_info.pickle','wb')as usr_file: (3)
usrs_info={'admin':'admin'}
pickle.dump(usrs_info,usr_file)
建议打开文件时,除了用with ... as ...语句块,还用try ... except ...语句块,前者可以避免文件没有关闭造成的数据泄露,后者可以预防一些异常。
这里用try ... except ...处理文件不存在时候的情况,处理方式为新建一个文件,并写入一个默认用户信息。
这里用了pickle库的load和dump方法进行序列化和反序列化,序列化可以方便传输和保存,此外序列化后的数据为二进制数据,读写时必须标识是二进制读写,即rb和wb;另外,读取时必须反序列化,不然显示出来的还是二进制数据。
Python的序列化库pickle可以保存数据的类型,即将一个dict进行序列化后,再进行反序列化,得到的仍是一个dict(这一点很重要)。所以我们用usrs_info保存读进来的数据,usrs_info仍是dict类型
(4)、(5)
if usr_name in usrs_info:
if usr_pwd == usrs_info[usr_name]: (4)
messagebox.showinfo(title='Welcome',message='How are you? '+usr_name)
else:
messagebox.showerror(message='Error,your password is wrond,try again.')
else: (5)
is_sign_up=messagebox.askyesno('Welcome!','You have not signed up yet. Sign up please!')
if is_sign_up:
usr_sign_up()
usrs_info是(2)部分读入的用户信息,由于进行了反序列化,所以可以还原写入前的数据类型,即Dict,所以判断输入的用户名是否为其中的某个Key可以用in关键字。
所有用户的信息都以{'Username' : 'Password'}的字典形式保存在了变量usrs_info中,访问某个Username时,可以直接用usrs_info[ Username ]的方式,这样就可以取得需要用户名对应的密码了,这也是上文判断输入密码是否与该用户对应密码的方式:
if usr_pwd == usrs_info[usr_name]:
这种通过序列化和反序列化的方式无损存储数据类型的方式是很有用的。
当判断完毕之后,就可以通过弹出信息框的方式直观说明了,关于messagebox的几种形式,可以见tkinter(二)部分的内容。这里只补充一下messagebox生成消息弹出框时最常用的参数设置:
messagebox.showxxx(title='xxx',message='xxx')
title与message,分别给出了弹出框的标题和内容
而以ask开头的弹出框,还会返回一个bool值,当勾选“确认”时,返回True,勾选“取消”时,返回False。可以以此法收集用户消息,进而进行下一步的处理。比如上文中用is_sign_up变量承接,就可以通过该值判断用户是否选择了注册,如果是,则进行注册功能,否的话,就继续原程序执行了。
(6)
def usr_sign_up():
def sign_to_Le_Website():
这里是注册函数usr_sign_up,负责注册界面生成和注册功能实现。注册功能实现用函数sign_to_Le_Website,之所以功能实现函数写的这么靠前,是因为函数调用必须要在其实现之后。由于在(14)部分调用了该函数作为button的响应函数,所以该函数必须在(14)之前实现。
(7)——(11)都是sign_to_Le_Website的内容,由于其中的一些变量用到了一些外部变量(比如一些输入框传入的变量),所以建议先看(8)——(14)部分,这一部分为注册界面的实现
(7)
np=new_pwd.get()
npf=new_pwd_confirm.get()
nn=new_name.get()
这三个变量为从(13)部分建立的三个输入框传入的三个用户输入值,分别表示欲创建的用户名、密码和确认密码
(8)
#打开我们记录数据的文件,将注册信息读出
with open('usrs_info.pickle','rb') as usr_file:
exist_usr_info=pickle.load(usr_file)
从用户文件中将已有的用户信息读入,以便进行后续判断。
(9)、(10)
if np!=npf: (9)
messagebox.showerror('Error','Password and confirm password must be the same')
#如果用户名已经在我们的数据文件中,则提示Error,用户已注册
elif nn in exist_usr_info:
messagebox.showerror('Error','The user has already signed up!')
#输入正确时
else:
exist_usr_info[nn]=np (10)
with open('usrs_info.pickle','wb') as usr_file:
pickle.dump(exist_usr_info,usr_file)
messagebox.showinfo('Welcome','You have successfully signed up!')
这部分是检验输入内容是否合法,三个判断语句分别表示三种情况:密码和确认密码不同、用户名已存在、输入正确;
对不同情况进行分别处理,前两种情况均属于异常情况,用弹出框标识即可,并不需要做额外的处理;
正确情况下,就需要向用户文件中写入新注册的用户信息:先为用户信息Dict添加一项,给Dict添加一项的方式很简单,并不像List那样还需要用到append方法,而是直接用 dict [ 'new_name' ] = 'new_pwd'即可完成添加。之后再通过序列化方式将更新后的用户信息dict保存到文件中即可,最后再通过弹出框向用户标识已经成功注册。
(11)
window_sign_up.destroy()
注册完成后,注册窗口就没必要再存在了,使用destroy()方法销毁。及时销毁程序运行过程中产生的子功能窗口对于提高用户体验很有帮助。
(12)——(14)
window_sign_up=Toplevel(window) (12)
window_sign_up.geometry('300x200')
window_sign_up.title('Sign up window') new_name=StringVar()
new_name.set('example@python.com')
Label(window_sign_up,text='Username:').place(x=10,y=10)
entry_new_name=Entry(window_sign_up,textvariable=new_name)
entry_new_name.place(x=130,y=10) new_pwd=StringVar() (13)
Label(window_sign_up,text='Password:').place(x=10,y=50)
entry_usr_pwd_confirm=Entry(window_sign_up,textvariable=new_pwd,show='*')
entry_usr_pwd_confirm.place(x=130,y=50) new_pwd_confirm=StringVar()
Label(window_sign_up,text='Confirm Password:').place(x=10,y=90)
entry_usr_pwd_confirm=Entry(window_sign_up,textvariable=new_pwd_confirm,show='*')
entry_usr_pwd_confirm.place(x=130,y=90) btn_confirm_sign_up=Button(window_sign_up,text='Sign up',command=sign_to_Le_Website)
btn_confirm_sign_up.place(x=180,y=120) (14)
(12)
由于要额外生成一个界面,所以利用Toplevel生成额外一个弹窗,创建方式与其他的控件类似,也可以通过title和geometry进行标题和形状设置。
(13)
这一部分生成了三个输入框及这三个输入框之前的说明文本,生成方式和⑤、⑥部分所述完全相同,这里不再赘述
(14)
生成了一个利用输入的用户名和密码进行注册的按钮,点击该按钮即可实现输入内容登记到用户文件中,响应函数为sign_to_Le_Website,正是该函数完成了登记功能。下面我们就可以回头看(7)——(11)部分关于函数内容的详细说明了。
⑧
#登录与注册按钮,关联函数 ⑧
btn_login=Button(window,text='Login',command=usr_login)
btn_login.place(x=120,y=240)
btn_sign_up=Button(window,text='sign_up',command=usr_sign_up)
btn_sign_up.place(x=200,y=240)
在主界面上创建两个按钮,分别实现两个功能:登录和注册,分别用对应的功能函数来实现。
⑨
#运行主框架 ⑨
window.mainloop()
每个GUI程序运行时,都必须使主窗口一直运行,所以这句话是每个GUI程序都要有的。
Python:GUI库tkinter(三)的更多相关文章
- Python:GUI库tkinter(一)
学习自: Python GUI 编程(Tkinter) | 菜鸟教程 TkDocs_官方文档 1.几个常用的Python GUI库 tkinter:Python的标准Tk GUI工具包的接口. wxP ...
- Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介
Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...
- Python:GUI库tkinter(二)
学习自: Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) - 洪卫 - 博客园 Tkinter简明教程 - 知乎 TkDocs_官方文档 一个Tkinter库较为全面的总结,很 ...
- 8个必备的Python GUI库
Python GUI 库有很多,下面给大家罗列常用的几种 GUI 库.下面介绍的这些GUI框架,能满足大部分开发人员的需要,你可以根据自己的需求,选择合适的GUI库. 很多人学习python,不知道从 ...
- Python GUI编程(Tkinter) windows界面开发
Python实现GUI简单的来说可以调用Tkinter库,这样一般的需求都可以实现,显示简单的windows窗口代码如下: python_gui.py 1 #!C:\Python27\python.e ...
- 使用Python3.6的标准GUI库tkinter快速创建GUI应用程序
Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 ...
- Python GUI with Tkinter (from youtube) 在youtube上能找到很多编程视频...
Python GUI with Tkinter - 1 - Introduction以上链接是一个python tkinter视频系列的第一讲的链接.虽然英语不好,但是,程序还是看得懂的(照着做就可以 ...
- Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)
一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 二.Tkinter 是什么 三.Tkinter 控件详细介绍 1. T ...
- Python GUI编程--Tkinter
今天看到了GUI编程,书上推荐用wxPython,去官网上看了看,发现Windows的最高支持到2.7,我用的是3.4版本,咋办,用自带的库--Tkinter呗,它是Python的默认GUI库,几乎是 ...
随机推荐
- Ventoy的UEFI模式安全启动操作说明
Ventoy 1.0.07 版本开始支持 Secure Boot (安全启动),但是这个方案不是非常的完美,会导致在一些机器上不管BIOS里安全启动是否关闭都不能正常工作.因此从 1.0.09 版本开 ...
- ApacheCN jQuery 译文集 20211121 更新
创建 jQueryMobile 移动应用 零.序言 一.jQueryMobile 原型制作 二.jQuery Mobile 网站 三.分析.长表单和前端验证 四.QR 码.地理位置.谷歌地图 API ...
- kali切换桌面环境
感谢大佬:https://blog.csdn.net/tao546377318/article/details/52353018 kali 是基于Debian的发行版,兼容性和软件支持都很好,默认使用 ...
- 广播接收者案例_sd卡状态监听
(1)定义广播接收者 import android.content.BroadcastReceiver; import android.content.Context; import android. ...
- 增删改查简单的sql语句
insert INSERT INTO t_stu (name,age) VALUES ('wang',12) INSERT INTO t_stu VALUES(NULL,' ...
- Note/Solution - 转置原理 & 多点求值
\[\newcommand{\vct}[1]{\boldsymbol{#1}} \newcommand{\mat}[1]{\begin{bmatrix}#1\end{bmatrix}} \newcom ...
- 海盗湾The Pirate Bay:每一名技术人员都应该思考的问题
海盗湾The Pirate Bay:一场互联网技术下没有硝烟的战争 写在前面: 开学啦,返校啦!祝大家新的一年,工作顺顺利利,家庭幸福美满! 正文: 假期的时候,闲来无事,看了几部纪录片,其中< ...
- 【软件实施面试】MySQL和Oracle联合查询以及聚合函数面试总结
软件实施面试系列文章第二弹,MySQL和Oracle联合查询以及聚合函数的面试总结.放眼望去全是MySQL,就不能来点Oracle吗?之前面过不少公司,也做过不少笔试题,现在已经很少做笔试题了.你肚子 ...
- 主机磁盘使用率超过85%导致es索引变为只读模式
[ type=cluster_block_exception, reason=index [ index_name ] FORBIDDEN/12/index read-only / allow del ...
- MySQL架构原理之存储引擎InnoDB线程模型
如下图示,为InnoDB线程模型示意图: 1.IO Thread 在InnoDB中使用了大量的AIO(Async IO)来做读写处理,这样可以极大提高数据库的性能.其提供了write/read/ins ...