TKinter学习_基础知识和登陆页面实战项目(1)
前言用python自带的GUI库tkinter开发东西比较敏捷所以TKinter这个系列学习的目标是知道怎么用这个工具同时可以加固对python的学习成果了解python进行项目开发的方式。本文中只涉及基础知识和基础开发相关控件。一、第一部分基础知识1.1、基础概念GUIGraphical User Interface用户图像界面控件用户图形界面中的元素就是控件比如菜单栏、文本框、按钮等普通python程序和GUI程序的区别普通程序是按照顺序执行GUI程序是事件驱动的程序常见的GUI程序框架有QtTKinterJava Swing等他们的核心思想都是“等待事件发生后再执行对应的代码”。TKinter是python自带的GUI库1.2、第一个tkinter程序认识TKinter创建GUI程序的核心结构第一个程序认识GUI程序和普通程序的不同importtkinterastk 导入TKinter库后面所有控件都从这里创建 importtimeif__name____main__:print(f程序开始)# 窗口创建前打印time.sleep(1)# 模拟耗时操作roottk.Tk()# 创建主窗口后面所有控件都放这个窗口对象中root.title(Hello Tkinter)# 设置窗口标题root.mainloop()# 进入消息循环没有这个代码程序一闪而过print(f程序结束)# 窗口关闭后打印TKinter程序执行流程启动程序导入库创建对象创建控件给控件布局进入消息循环等待用户操作。如果把制作GUI程序比喻成盖房的话通过第一个程序我们只是搭建了一个空房间至于房间如何装修设计实现什么功能这就是后续要做的了。1.3、第二个tkinter程序装修TKinter程序中的主窗口对象root第二个程序就可以开始装修我们用tkinger创建的窗口了。窗口标题、大小、位置、背景颜色、窗口缩放、窗口尺寸、窗口状态importtkinterastkif__init____main__:rttk.Tk()rt.title(修饰主窗口)# 窗口标题rt.geometry(800x80010050)# 窗口大小800*800和位置距离左边100上面50rt.configure(bglightblue)# 修改窗口颜色16进制配色也行#87CEFA# rt.resizable(False,False) # 锁死宽度锁高度rt.minsize(400,400)# 设置最小尺寸rt.maxsize(1200,1200)# 设置最大尺寸rt.state(normal)# 设置窗口正常显示rt.mainloop()二、登陆页面项目驱动实战2.1、第三个tkinter程序写要给登录系统学习一些重要控件通过常用控件写登录页面用第一阶段学到的 Tkinter 知识完成一个简单但完整的登录系统。了解界面、控件、布局、事件、逻辑之间的关系界面是容器控件是元件布局管摆放事件当触发器逻辑做处理五者共同完成「用户操作→系统响应→界面更新」的 GUI 交互闭环。概念说明界面最外层窗口Tk()实例所有内容的载体相当于整张“画布”控件按钮、输入框、标签等可视化组件Button/Entry/Label等是用户交互的实体元件布局pack / grid / place三类排布规则决定控件在窗口中的位置、大小和排列相当于“排版规则”事件用户操作点击、输入、关闭窗口或系统触发的信号是交互的触发开关逻辑绑定在事件上的 Python 函数负责实际业务处理、数据计算和界面更新tkinter布局管理布局特点使用场景pack()按方向排列布局告诉tk这个控件放到上面/下面/左边/右边简单界面grid()表格布局登录、表单最常用place()绝对坐标布局特殊场景功能需求✅ 输入用户名✅ 输入密码✅ 点击登录验证✅ 点击退出关闭窗口✅ 错误/成功弹窗开发流程创建窗口、Frame布局、添加控件、添加事件逻辑。使用Frame是因为后续主窗口中功能复杂了功能区多了不好区分控件所以Frame框架就是窗口里面的小窗口。 计划设计三个Frame区域第一个是标题区、第二个是中心区、第三个是按钮区。在开发中控件的使用逻辑也是先创建再布局。Tkinter里面大部分控件都可以绑定事件但绑定方式和事件类型有区别。按钮类控件主要用 command命令回调回调函数不需要传入事件对象event但它只能绑定控件提供的特定动作。其他控件主要用 bind()去绑定控件创建的对象出现某一类事件时bind() 是更底层的事件系统监听的是控件发生了某种事件之后要去做什么例如鼠标进入之后要做啥这就需要将控件对象的某个事件和对应的自定义函数绑定起来且自定义函数中要有event作为参数传入。如下所示就是项目最终版的程序了这个程序就是根据tkinter开发的一般模板来写的之后写tkinter应用可以参考。更通用的tkinter项目开发一般采用面向对象的方式。importtkinterastkfromtkinterimportmessageboxfromtkinterimportttk# 引入tkinter中的ttk模块ttk是tkinter的扩展模块提供了更多的控件和样式 tk和ttk的控件库各自不同但是布局管理器是相同的tkinter提供了三种布局管理器pack、grid和placettk控件样式更丰富一些。 这个例子中没用到ttk classLoginWindow:def__init__(self):# 创建窗口self.rttk.Tk()# 创建主窗口self.rt.title(用户登陆系统)# 窗口标题self.rt.geometry(500x70010050)# 窗口大小长*高和位置距离左边100上面50self.rt.resizable(False,False)# 锁死宽度锁高度# 创建界面self.create_widgets()# 创建界面函数其中创建控件最好都用self创建后面就是可以调用的全局变量。defcreate_widgets(self): 布局划分 # 顶部区域self.frame_toptk.Frame(self.rt,bglightblue,width500,height100)# 创建顶部区域设置背景颜色和高度self.frame_top.pack(filltk.X)# 顶部区域填充整个宽度self.frame_top.pack_propagate(False)# 关闭frame_top的自适应大小功能防止frame_top的高度被子控件变大或者变小# 中间区域self.frame_middletk.Frame(self.rt,bglightgreen,width500,height400)# 创建中间区域设置背景颜色和高度self.frame_middle.pack(filltk.X)# 中间区域填充整个宽度self.frame_middle.pack_propagate(False)# 关闭frame_middle的自适应大小功能防止frame_middle的高度被子控件变大或者变小# 底部区域self.frame_bottomtk.Frame(self.rt,bglightyellow,width500,height200)# 创建底部区域设置背景颜色和高度self.frame_bottom.pack(filltk.X)# 底部区域填充整个宽度self.frame_bottom.pack_propagate(False)# 关闭frame_bottom的自适应大小功能防止frame_bottom的高度被子控件变大或者变小# 使用pack布局管理器将三个区域添加到主窗口中 顶部布局 self.title_labeltk.Label(self.frame_top,text用户登录系统,font(微软雅黑,20),backgroundwhite)self.title_label.pack(pady20,# 这是title_label这个控件距离frame_top这个父控件的上边距和下边距都是20像素# tkinter 默认 pack 会水平居中此处移除无效的 padx) 中部布局 # frame_middle_content 是用来让中间控件居中显示的容器设置宽度为400像素通过pack_propagate关闭了自适应功能self.frame_middle_contenttk.Frame(self.frame_middle,width400,height200,bglightyellow,bd2,# 查看具体大小reliefsolid)self.frame_middle_content.pack_propagate(False)self.frame_middle_content.pack(expandTrue)# 设置grid整体居中self.frame_middle_content.grid_columnconfigure(0,weight1)# 两个参数分别是列索引和权重权重越大列占据的空间越大self.frame_middle_content.grid_columnconfigure(1,weight1)# 用户名及其输入部分self.user_labeltk.Label(self.frame_middle_content,text用户名,font(微软雅黑,16))self.user_label.grid(row0,column0,padx10,pady30)self.user_entrytk.Entry(self.frame_middle_content,width25,font(微软雅黑,16))self.user_entry.grid(row0,column1,padx10,pady30)# 给输入框对象绑定事件当输入框获得焦点时调用user_focus函数# 格式控件.bind(事件类型, 事件函数)self.user_entry.bind(FocusIn,self.user_focus)# 密码及其输入部分self.password_labeltk.Label(self.frame_middle_content,text密 码,font(微软雅黑,16))self.password_label.grid(row1,column0,padx10,pady30)self.password_entrytk.Entry(self.frame_middle_content,width25,font(微软雅黑,16),show*)self.password_entry.grid(row1,column1,padx10,pady30)# 给输入框对象绑定事件当输入框获得焦点时调用password_focus函数self.password_entry.bind(FocusIn,self.password_focus)# 查看控件大小长宽self.rt.update()# 更新窗口确保所有控件都已经渲染完成print(frame_middle_content size:,self.frame_middle_content.winfo_width(),self.frame_middle_content.winfo_height())print(password_label size:,self.password_label.winfo_width(),self.password_label.winfo_height()) 底部布局 # 对比grid布局# frame_top.grid(row0, column0, stickyew) # 顶部区域占据第一行填充整个宽度# frame_middle.grid(row1, column0, stickyew) # 中间区域占据第二行填充整个宽度# frame_bottom.grid(row2, column0, stickyew) # 底部区域占据第三行填充整个宽度# 对比place布局# frame_top.place(x0, y0, width500, height100) # 顶部区域放置在(0,0)宽度500高度100# frame_middle.place(x0, y100, width500, height400) # 中间区域放置在(0,100)宽度500高度400# frame_bottom.place(x0, y500, width500, height200) # 底部区域放置在(0,500)宽度500高度200# 设置grid整体居中self.frame_bottom.grid_columnconfigure(0,weight1)self.frame_bottom.grid_columnconfigure(1,weight1)# 登录按钮login_buttontk.Button(self.frame_bottom,text登录,font(微软雅黑,16),width10,height1,commandself.function_login# 登录按钮点击事件调用function_login函数)login_button.grid(row0,column0,padx20,pady50)# 退出按钮exit_buttontk.Button(self.frame_bottom,text退出,font(微软雅黑,16),width10,height1,commandself.rt.quit# 退出按钮点击事件调用rt.quit函数)exit_button.grid(row0,column1,padx20,pady50) 通过事件绑定的函数 defuser_focus(self,event):print(请输入用户名)defpassword_focus(self,event):print(请输入密码)# 定义绑定登录按钮点击事件的函数deffunction_login(self):usernameself.user_entry.get()# 获取用户名输入框的内容passwordself.password_entry.get()# 获取密码输入框的内容ifusernameadminandpassword123456:# 判断用户名和密码是否正确messagebox.showinfo(登录成功,欢迎{}.format(username))# 弹出登录成功消息框else:messagebox.showerror(登录失败,用户名或密码错误)# 弹出登录失败消息框defrun(self):self.rt.mainloop()if__name____main__:appLoginWindow()app.run()后续进行大项目开发会用的一般文件分层方式如下login_system/│├── main.py│├── ui/│ └── login_window.py│├── database/│ └── user_db.py│└── config.py2.2、总结tkinter开发中各关键要素之间的关系承载关系界面是根容器所有控件必须依附于界面布局作用于控件把控件 “摆放” 到界面中。触发关系用户操作控件 → 产生对应事件 → 触发预先绑定的逻辑函数。反馈闭环逻辑执行后可修改控件属性文字、颜色、内容反过来更新界面显示完成一次完整交互。三、tkinter学习进度分析