本节知识大纲: 本节知识框架 Python里的图形化界面(GUI)模块主要有Tkinter(python自带)、PyQt、wxPython,我们这节主要讲解Tkinter组件: 一、Tkinter介绍tkinter模块只要用户安装好Python环境就可以直接使用; 1. 第一个tkinter程序import tkinter as tk # 给tkinter重命名为tkroot = tk.Tk() # 新建一个窗体root.mainloop() # 展示窗体 2. 设置属性并添加控件设置窗体标题、指定窗体大小、添加按钮、输入框、标签并布局
二、控件的属性1. tkinter常用的控件属性(1)定义控件的名称使用参数text,传入的字符串值即为控件的名称; (2)定义控件高度使用参数hight,宽度使用参数width,传入的值为整形数值; (3)定义控件在空间中的位置,使用参数anchor,传入的字符参数为e、s、w、n以地图的东南西北来定义为右下左上,也可以同时设置左下sw、左上nw、右下se、右上ne; (4)定义控件的背景色,使用参数bg,前景色使用参数fg,传入字符值可以直接是对应颜色的英文名称; (5)设置布局在pack()函数里,使用参数side,传入的值为常量tk.LEFT或者tk.RIGHT,表示从左到右或者从右到左布局 (6)创建图片控件时,图片控件的文件源使用参数file,传入的字符值为为文件路径,在控件中使用图片则使用参数image,传入的值为图片控件变量; (7)设置整个窗体的尺寸,使用参数geometry,传入的值为字符值,注意乘号用小写字母x代替;如果要设置长400宽300的窗体则使用语句geometry = '400x300' (8)设置控件与边界的距离在pack函数里使用参数padx,设置左右距离;使用pady设置上下距离。 2. 案例演示:画出一个简单的窗体布局import tkinter as tk# 新建一个窗体名称:rootroot = tk.Tk()# 为窗体添加一个标题root.title('第二个Python窗体')# 新建标签photo = tk.PhotoImage(file = '/Users/yushengtan/Desktop/image.png')Label01 = tk.Label(root,text = '第一个Label标签',anchor = 'se').pack(side = tk.LEFT)imageLable01 = tk.Label(root,image = photo).pack(side = tk.LEFT)Label02 = tk.Label(root,text = '第二个Label标签',bg = 'blue',fg = 'white',font = ('华文宋体',20)).pack()Label03 = tk.Label(root,text = '第三个Label标签',).pack()Label04 = tk.Label(root,text = '第四个Label标签').pack()Label05 = tk.Label(root,text = '第五个Label标签').pack()Button01 = tk.Button(root,text = '确定').pack()# 显示root.mainloop() 效果演示: 简单窗体布局 3. 案例演示:画出能计算加法的计算器界面
界面效果: 三、基本布局1. place绝对布局pack布局是按顺序布局,而place布局可以直接定义绝对位置,只需要给place()函数里传入两个参数x和y,其值为整型数值表示相对于窗体左上角的坐标位置;用法:place(x=10,y=20) 案例演示:绘制一个简易的登录界面 from tkinter import *root = Tk()root.title('用户登录')root.geometry('400x180')Label_username = Label(root,text = '登录名:',font = ('华为黑体',16)).place(x = 50,y = 20)Entry_username = Entry(root,font = ('华文黑体',16),width = 20).place(x = 120,y = 20)Label_password = Label(root,text = '密 码:',font = ('华为黑体',16)).place(x = 50,y = 60)Entry_password = Entry(root,font = ('华文黑体',16),width = 20).place(x = 120,y = 60)Button_login = Button(root,text = '登录',font = ('华文黑体',16),width = 8).place(x = 70,y = 120)Button_cancer = Button(root,text = '取消',font = ('华文黑体',16),width = 8).place(x = 210,y = 120)root.mainloop() 运行效果:2. grid表格布局grid是一种网格布局,grid(row = 1,column = 2),n行n列分别表示表格的行数和列数,从0开始计数;可以使用参数sticky控制控件靠近单元格的位置,字符值可以给出n、s、w、e设置上、下、左、右,我们还是以登录窗体为例:
输出效果:
四、使用类封装GUI这里我们使用类来封装GUI程序,以至于我们后面需要调用的时候直接实例化一个对象就可以产生一个窗口,类与对象的知识我们后面会深入讲解,现在我们只需怎么使用即可;我们把前面的登录窗口通过类来进行封装 from tkinter import *class login_GUI(object): def __init__(self): ''' 窗体的构造函数,用来做界面的初始化,GUI代码放在此函数中 ''' self.frame = Tk() self.frame.title('登录窗体') self.frame.geometry('400x160') self.photo = PhotoImage(file='/Users/yushengtan/Desktop/login.png') imgLabel = Label(self.frame, image=self.photo).grid(row=0, column=0, rowspan=2) # 第一行 第一列 Label_username = Label(self.frame, text='用户名:', font=('微软雅黑', 14)).grid(row=0, column=1) # 第一行 第二列 Entry_username = Entry(self.frame, font=('华文黑体', 16)).grid(row=0, column=2) # 第二行 第二列 Label_password = Label(self.frame, text='密 码:', font=('华文黑体', 16)).grid(row=1, column=1) # 第二行 第三列 Entry_password = Entry(self.frame, font=('华文黑体', 16)).grid(row=1, column=2) # 第四行 第二列 Button_login = Button(self.frame, text='登录', width=8, font=('华文黑体', 16)).grid(row=3, column=2, sticky='e') # 第四行 第三列 Button_cancer = Button(self.frame, text='取消', width=8, font=('华文黑体', 16)).grid(row=3, column=2, sticky='w') def run(self): self.frame.mainloop()if __name__ == '__main__': # 由窗体的模板实例化一个具体的登录窗体 this_login = login_GUI() # 展示窗体 this_login.run() 五、响应事件以上我们实现了GUI界面的设计,加法计算器、登录窗口,但是没有程序并不能工作,如果想要程序工作起来还得给控件设置响应事件;事件是什么呢?事件就是响应某一个动作,如点击某一个按钮、输入键盘的某一个键等等。我们现在来完善前面设计加法计算器,让其能真正做加法计算; 1. 完成点击按钮响应事件的步骤(1)完成时间的功能---函数 (2)把功能捆绑到按钮上,添加command参数,其值为功能函数名,注意没有小括号,这一点非常重要,很多时候出错了,都不知道错在哪了,就是因为不小心加了括号! 注意:取出文本框的数值可以使用get()方法,设置文本框的数值可以使用set()方法;控件基本属性的设定和控件的布局语句要分开; 2. 案例:实现两数相加的功能通过响应事件完成加法计算器
运行效果: 3. 案例:实现用户登录功能需求: (1)如果用户名为admin,密码为123.com,显示登录成功! (2)如果用户名不对,显示用户名不存在; (3)如果密码不对,显示密码错误,如果错误三次,提示:账号已锁定。 提示:实现窗体的关闭,可以使用方法self.frame.destory()关闭窗体; # 用户登录from tkinter import *from tkinter.messagebox import *class login_GUI(object): def __init__(self): ''' 窗体的构造函数,用来做界面的初始化,GUI代码放在此函数中 ''' self.frame = Tk() self.frame.title('登录窗体') self.frame.geometry('400x160') self.photo = PhotoImage(file='/Users/yushengtan/Desktop/login.png') self.imgLabel = Label(self.frame, image=self.photo) self.imgLabel.grid(row=0, column=0, rowspan=2) # 第一行 第一列 self.Label_username = Label(self.frame, text='用户名:', font=('微软雅黑', 14)) self.Label_username.grid(row=0, column=1) # 第一行 第二列 self.Entry_username = Entry(self.frame, font=('华文黑体', 16)) self.Entry_username.grid(row=0, column=2) # 第二行 第二列 self.Label_password = Label(self.frame, text='密 码:', font=('华文黑体', 16)) self.Label_password.grid(row=1, column=1) # 第二行 第三列 self.Entry_password = Entry(self.frame, font=('华文黑体', 16)) self.Entry_password.grid(row=1, column=2) # 第四行 第二列 self.Button_login = Button(self.frame, text='登录', width=8, font=('华文黑体', 16),command = self.login) self.Button_login.grid(row=3, column=2, sticky='e') # 第四行 第三列 self.Button_cancer = Button(self.frame, text='取消', width=8, font=('华文黑体', 16),command = self.cancer) self.Button_cancer.grid(row=3, column=2, sticky='w') # 定义全局变量 self.password_error_times = 0 self.is_disable = False def run(self): self.frame.mainloop() def login(self): # 【1】先获取用户名和密码 username = str(self.Entry_username.get()) password = str(self.Entry_password.get()) # 【2】验证 if username.strip().lower() != 'admin': showinfo('系统消息','用户名不存在,请核实后再登录!') elif password.strip() != '123.com': self.password_error_times += 1 # 判断是否达到三次 if self.password_error_times >= 3: self.is_disable = True # 判断禁用标志 if self.is_disable: showinfo('系统消息','密码输入错误已达三次,账号已锁定,请联系管理员') else: showinfo('系统消息', '密码错误!') else: showinfo('系统消息','登录成功') # 如果在3次以内输入正确,则错误次数计数归零 self.password_error_times = 0 def cancer(self): # 实现窗体的关闭 self.frame.destroy()if __name__ == '__main__': # 由窗体的模板实例化一个具体的登录窗体 this_login = login_GUI() # 展示窗体 this_login.run() 演示效果: 六、GUI扩展功能1. ttk模块ttk模块是对传统tkinter模块的增强,传统的tkinter模块界面比较单一,控件种类有限,界面布局逻辑性差。ttk模块是tkinter下的一个子模块,它的界面比tkinter更丰富更美观。ttk的用法同tkinter大体相同,但是有一些属性ttk不再支持,而tkinter中的fg、bg、font属性在ttk中不再被支持,取而代之的是style对象; 2. 复选框Checkbutton
演示效果: 3. 单选框Radiobutton# RadioButtonfrom tkinter import *# from tkinter.ttk import *# radiobutton --- 单选框----多个值中只能选一个root = Tk()root.title('RadioButton组件')root.geometry('400x100')def sel_gender(): if gender_check.get() == 1: Label_select_gender['text'] = '男' else: Label_select_gender['text'] = '女'def sel_education(): Label_select_education['text'] = education_list[int(education_check.get())]# 性别单选Label_gender = Label(root,text = '性别:')Label_gender.grid(row = 0,column = 0,padx = 5,pady = 5)gender_check = IntVar()# 用哪个变量接收它是否被选中,variable,绑定的值是同一个表示一组,variable通过get方法能获得value的值# 最终选中后取什么值: value,同一组radiobutton中value的值最好是不同的# 性别的单选radio_boy = Radiobutton(root,text = '男',variable = gender_check,value = 1,command = sel_gender)radio_boy.grid(row = 0,column = 1,padx = 5,pady = 5)radio_boy = Radiobutton(root,text = '女',variable = gender_check,value = 0,command = sel_gender)radio_boy.grid(row = 0,column = 2,padx = 5,pady = 5)# 学历education_list = ['高中','专科','本科','硕士','博士']Label_education = Label(root,text = '学历:')Label_education.grid(row = 1,column = 0,padx = 5,pady = 5)education_check = IntVar()for i in range(0,len(education_list)): radio = Radiobutton(root,text = education_list[i],variable = education_check,value = i,command = sel_education) radio.grid(row = 1,column = i + 1,padx = 5,pady = 5)Label01 = Label(root,text = '所选的值为:')Label01.grid(row = 2 , column = 0)Label_select_gender = Label(root,text = '')Label_select_gender.grid(row = 2 , column = 1)Label_select_education = Label(root,text = '')Label_select_education.grid(row = 2 , column = 2)# 展示控件root.mainloop() 演示效果: 4. 下拉框ComboBox
效果演示: 5. 容器LabelFrame把具有相同功能的模块组合在一起,并且加上一个名字,这个控件能让你的界面更加有条理 # LabelFramefrom tkinter import *from tkinter.ttk import *root = Tk()root.title('LabelFrame控件')LabelFrame_query = LabelFrame(root,text = '学生信息查询')LabelFrame_query.pack(padx = 10,pady = 10)# 如果不加控件的话,LabelFrame是看不见的Label01 = Label(LabelFrame_query,text = '学号')Label01.pack(side = LEFT,padx = 5,pady = 5)Entry01 = Entry(LabelFrame_query,width = 10)Entry01.pack(side = LEFT,padx = 5,pady = 5)Label02 = Label(LabelFrame_query,text = '姓名')Label02.pack(side = LEFT,padx = 5,pady = 5)Entry02 = Entry(LabelFrame_query,width = 10)Entry02.pack(side = LEFT,padx = 5,pady = 5)Label03 = Label(LabelFrame_query,text = '班级')Label03.pack(side = LEFT,padx = 5,pady = 5)Entry03 = Entry(LabelFrame_query,width = 10)Entry03.pack(side = LEFT,padx = 5,pady = 5)Button01 = Button(LabelFrame_query,text = '查询',width = 5)Button01.pack(side = LEFT,padx = 15,pady = 5)root.mainloop() 运行效果: ![]() 6. 树状视图TreeView
运行效果: ![]() 7. Style属性增强的ttk包里没法用tkinter的传统属性进行设置比如bg和fg,我们需要通过style对象来对其设置;注意:我们对实例化对象style01进行配置, style01.configure('TLabel',font = ('华文黑体',18),background = 'green',foreground = 'blue') 第一个参数不是对象的名称,而是对象的某一类,其名称是有规定的,不是随便取的,由于这里是对Label 的style进行命令,所以我们只能命名成TLabel,具体的组件与名称的对应关系如下: ![]() Style对象名称
效果演示: ![]() 拓展:如果只想对某类中的某些控件生效,那么就必须要使用custom.Stylename格式来进行命名;如我创建的style01的Stylename名称是username.TLabel,这里的username是自定义字段,那么后面的Label控件如果没有指定style是username.TLabel就不会具有style01的属性 from tkinter import *from tkinter.ttk import *root = Tk()root.title('style属性')root.geometry('300x200')# 实例化一个style对象style01style01 = Style()# 对style01进行配置,Stylename属性设置为password.TLablestyle01.configure('password.TLabel',font = ('华文黑体',18),background = 'green',foreground = 'blue')# 把Label01控件绑定给style01对象Label01 = Label(root,text = '用户名',style = 'password.TLabel')Label01.pack(padx = 10,pady = 10)Label02 = Label(root,text = '密码')Label02.pack(padx = 10,pady = 10)# 展示窗体root.mainloop() 这样控件的显示效果如下: ![]()
|
|