关于Tkinter
Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。
Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口。作为 python 特定的GUI界面,是一个图像的窗口,tkinter是python 自带的,可以编辑的GUI界面,我们可以用GUI 实现很多直观的功能,比如想开发一个计算器,如果只是一个程序输入,输出窗口的话,是没用用户体验的。所有开发一个图像化的小窗口,就是必要的。
对于稍有GUI编程经验的人来说,Python的Tkinter界面库是非常简单的。python的GUI库非常多,选择Tkinter,一是最为简单,二是自带库,不需下载安装,随时使用,三则是从需求出发,Python作为一种脚本语言,一种胶水语言,一般不会用它来开发复杂的桌面应用,它并不具备这方面的优势,使用Python,可以把它作为一个灵活的工具,而不是作为主要开发语言,那么在工作中,需要制作一个小工具,肯定是需要有界面的,不仅自己用,也能分享别人使用,在这种需求下,Tkinter是足够胜任的!
Tkinter 编程
Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。
由于 Tkinter 是内置到 python 的安装包中、只要安装好 Python 之后就能 import Tkinter 库、而且 IDLE 也是用 Tkinter 编写而成、对于简单的图形界面 Tkinter 还是能应付自如。
import tkinter
Tkinter 组件
Tkinter的提供各种控件,如按钮,标签和文本框,一个GUI应用程序中使用。这些控件通常被称为控件或者部件。
目前有15种Tkinter的部件。我们提出这些部件以及一个简短的介绍,在下面的表:
控件 | 描述 |
---|---|
Button | 按钮控件;在程序中显示按钮。 |
Canvas | 画布控件;显示图形元素如线条或文本 |
Checkbutton | 多选框控件;用于在程序中提供多项选择框 |
Entry | 输入控件;用于显示简单的文本内容 |
Frame | 框架控件;在屏幕上显示一个矩形区域,多用来作为容器 |
Label | 标签控件;可以显示文本和位图 |
Listbox | 列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户 |
Menubutton | 菜单按钮控件,用于显示菜单项。 |
Menu | 菜单控件;显示菜单栏,下拉菜单和弹出菜单 |
Message | 消息控件;用来显示多行文本,与label比较类似 |
Radiobutton | 单选按钮控件;显示一个单选的按钮状态 |
Scale | 范围控件;显示一个数值刻度,为输出限定范围的数字区间 |
Scrollbar | 滚动条控件,当内容超过可视化区域时使用,如列表框。. |
Text | 文本控件;用于显示多行文本 |
Toplevel | 容器控件;用来提供一个单独的对话框,和Frame比较类似 |
Spinbox | 输入控件;与Entry类似,但是可以指定输入范围值 |
PanedWindow | PanedWindow是一个窗口布局管理的插件,可以包含一个或者多个子控件。 |
LabelFrame | labelframe 是一个简单的容器控件。常用与复杂的窗口布局。 |
tkMessageBox | 用于显示你应用程序的消息框。 |
标准属性
标准属性也就是所有控件的共同属性,如大小,字体和颜色等等。
属性 | 描述 |
Dimension | 控件大小; |
Color | 控件颜色; |
Font | 控件字体; |
Anchor | 锚点; |
Relief | 控件样式; |
Bitmap | 位图; |
Cursor | 光标; |
实践1:制作一个BMI 计算器GUI程序
编写一个简单的界面,用户输入体重、身高,点击计算按钮,生成身体质量指数,简称体质数
示例代码
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import tkinter as tk from tkinter import ttk # 主体控件命名模块 class BMIView(tk.Frame): def __init__(self,parent,*args,**kwargs): super().__init__(parent,*args,**kwargs) # parent 指的是当前这个控件容器将会依附在哪个容器或者窗体之上 self.body_weight = tk.DoubleVar() self.height = tk.DoubleVar() self.bmi = tk.StringVar() lbl_body_weight = ttk.Label(self,text="体重(Kg):") entry_body_weight = ttk.Entry(self,textvariable=self.body_weight) lbl_height = ttk.Label(self,text="身高(m):") entry_height = ttk.Entry(self,textvariable=self.height) btn_calculate = ttk.Button(self,text="计算",command=self.on_calculate) lbl_bmi = ttk.Label(self,textvariable=self.bmi,font=("Microsoft Yahei",64),wraplength=480) lbl_body_weight.grid(row=0,column=0,sticky=tk.W) entry_body_weight.grid(row=0,column=1,sticky=(tk.W+tk.E)) lbl_height.grid(row=0,column=2,sticky=(tk.W+tk.E)) entry_height.grid(row=0,column=3,sticky=(tk.W+tk.E)) btn_calculate.grid(row=0,column=4,sticky=(tk.E)) lbl_bmi.grid(row=1,column=0,columnspan=5) # columnspan=5 合并5个单元格 self.columnconfigure(1,weight=1) self.columnconfigure(3,weight=1) def on_calculate(self): bmi = self.body_weight.get() / (self.height.get() ** 2) print('bmi:',bmi) self.bmi.set(f"{bmi:.1f}") class BMIApplication(tk.Tk): def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) self.title("BMI 计算器") self.geometry("640x180") self.resizable(width=False,height=False) BMIView(self).grid(sticky=(tk.E+tk.N+tk.W+tk.S)) self.columnconfigure(0,weight=1) if __name__ == '__main__': app = BMIApplication() app.mainloop()
测试功能:
实践2:制作一个简单登录的GUI程序
输入用户名、密码,点击登录
AC1:输入正确用户名、密码,点击登录,弹窗提示登录成功
AC2:输入错误用户名或密码,点击登录,弹窗提示登录异常
# !/usr/bin/env python3 # -*- coding:utf-8 -*- """使用Entry组件的基本用法,使用面向对象的方式""" import tkinter as tk from tkinter import messagebox class Application(tk.Frame): def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master = master self.pack() self.createWidget() def createWidget(self): global photo # 把photo声明成全局变量。如果是局部变量,本方法执行完毕后,图像对象销毁,窗口显示不出来 photo = tk.PhotoImage(file="imge/logo.png") self.label03 = tk.Label(self, image=photo) self.label03.pack() """创建界面登录的组件""" self.label01 = tk.Label(self,text="用户名") self.label01.pack() # StringVar变量绑定到指定组件 # StringVar变量的值发生变化,组件内容也变化 # 组件内容发生变化,StringVar变量的值也发生变化 v1 = tk.StringVar() self.entry01 = tk.Entry(self,textvariable=v1) self.entry01.pack() v1.set("admin") """创建密码框""" self.label02 = tk.Label(self, text="密码") self.label02.pack() v2 = tk.StringVar() self.entry02 = tk.Entry(self, textvariable=v2,show="*") self.entry02.pack() self.btn01 = tk.Button(self, text="登录", command=self.login) self.btn01.pack() def login(self): username = self.entry01.get() pwd = self.entry02.get() if username == "admin" and pwd == "123456": messagebox.showinfo("登录系统","登录成功!欢迎开始学习!") else: messagebox.showinfo("登录系统", "账号或密码错误,请重新输入") root = tk.Tk() root.geometry("400x300+600+400") root.title("测试Entry") app = Application(master=root) if __name__ == '__main__': root.mainloop()
实践3:操作TEXT的GUI程序
# !/usr/bin/env python3 # -*- coding:utf-8 -*- """使用Text组件的基本用法,使用面向对象的方式""" import tkinter as tk import webbrowser class Application(tk.Frame): def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master = master self.pack() self.createWidget() def createWidget(self): self.w1 = tk.Text(root,width=40,height=12,bg="gray") # 宽度20个字母(10个汉字),高度一个行高 self.w1.pack() self.w1.insert(1.0,"0123456789\nabcdefghijklmn") self.w1.insert(2.3,"锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦\n") tk.Button(self,text="重复插入文本",command=self.insertText).pack(side="left") tk.Button(self,text="返回文本",command=self.returnText).pack(side="left") tk.Button(self,text="添加图片",command=self.addImage).pack(side="left") tk.Button(self,text="添加组件",command=self.addWidget).pack(side="left") tk.Button(self,text="通过tag精确控制文本",command=self.testTag).pack(side="left") def insertText(self): # INSERT索引表示在光标处插入 self.w1.insert(tk.INSERT,' test ') # END索引表示在最后插入 self.w1.insert(tk.END,'[sxt]') def returnText(self): # Indexes(索引)是用来指向Text组件中文本的位置,Text的组件索引也是对应实际字符之间得位置 # 核心:行号以1开始,列号以0开始 print(self.w1.get(1.2,1.6)) self.w1.insert(1.8," test2 ") print("所有文本内容:\n"+self.w1.get(1.0,tk.END)) def addImage(self): self.photo = tk.PhotoImage(file="imge/logo.png") self.w1.image_create(tk.END,image=self.photo) def addWidget(self): b1 = tk.Button(self.w1,text="测试TEXT") # 在text创建组件的命令 self.w1.window_create(tk.INSERT,window=b1) def testTag(self): self.w1.delete(1.0,tk.END) self.w1.insert(tk.INSERT,"good good study,day day up!\n前端开发\n后端开发\n测试设计") self.w1.tag_add("good",1.0,1.9) self.w1.tag_config("good",background="yellow",foreground="red") self.w1.tag_add("baidu",4.0,4.2) self.w1.tag_config("baidu",underline=True) self.w1.tag_bind("baidu","<Button-1>",self.webshow) def webshow(self,event): webbrowser.open("https://www.baidu.com") root = tk.Tk() root.geometry("500x250+600+400") root.title("测试TEXT") app = Application(master=root) if __name__ == '__main__': root.mainloop()