GUI介绍
- GraphicalUserInterface,简称GUI–图形化界面
- python的GUI: Tkinter, wxPython, PyQt
- TKinter:
- Python标准库,绑定的是TK GUI工具集,简单易用
- PyGTK:
- wxPython:
- PyQt:
Tkinter常用组件
- 按钮
- Button 按钮组件
- RadioButton 单选框组件
- CheckButton 选择按钮组件
- Listbox 列表框组件
- 文本输入组件
- Entry 单行文本框组件
- Text 多行文本框组件
- 标签组件
- Label 标签组件,可以显示图片和文字
- Message 标签组件,可以根据内容将文字换行
- 菜单
- Menu 菜单组件
- MenuButton 菜单按钮组件,可以使用Menu代替
- 滚动条
- scale 滑块组件
- Scrollbar 滚动条组件
- 其他组件
- Canvas 画布组件
- frame 框架组件,将多个组件编组
- Toplevel 创建子窗口容器组件
---label实例---
import tkinter
# 创建主窗口
base = tkinter.Tk()
# 负责标题
base.wm_title("Label Test")
lb = tkinter.Label(base, text="Python Label")
# 给相应组件指定布局
lb.pack()
# 500x500 窗口大小,+200+50 窗口距左和上边缘的像素
base.geometry("500x500+200+50")
# 启动主窗口
base.mainloop()
---设置label实例---
import tkinter
base = tkinter.Tk()
base.wm_title("Label Test")
# 支持属性很多background, font,underline等
# 第一个参数,制定所属
lb1 = tkinter.Label(base, text="Python AI")
lb1.pack()
lb2 = tkinter.Label(base, text="绿色背景", background="green")
lb2.pack()
lb3 = tkinter.Label(base, text="蓝色背景", background="blue")
lb3.pack()
base.mainloop()
组件的大致使用步骤
- 创建总面板
- 创建面板上的各种组件
- 指定组件的父组件,即依附关系
- 利用相应的属性对组件进行设置
- 给组件安排布局
- 同步骤2相似,创建好多个组件
- 最后,启动总面板的消息循环
---Button实例---
import tkinter
def showLabel():
global baseframe
# 在函数中定义了一个label
# label的父组件是baseframe
lb = tkinter.Label(baseframe, text="显示Label")
lb.pack()
baseframe = tkinter.Tk()
# 生成一个按钮
# command参数指示,当按钮被按下的时候,执行哪个函数
btn = tkinter.Button(baseframe, text="Show Label", command=showLabel)
# btn = tkinter.Button(baseframe, text= "Show Label")
btn.pack()
baseframe.mainloop()
- Button的属性:
- anchor 设置按钮中文字的对其方式,相对于按钮的中心位置
- background(bg) 设置按钮的背景颜色
- foreground(fg) 设置按钮的前景色(文字的颜色)
- borderwidth(bd) 设置按钮边框 宽度
- cursor 设置鼠标在按钮上的样式
- command 设定按钮点击时触发的函数
- bitmap 设置按钮上显示的位图
- font 设置按钮上文本的字体
- width 设置按钮的宽度(字符个数)
- height 设置按钮的高度(字符个数)
- state 设置按钮的状态
- text 设置按钮上的文字
- image 设置按钮上的图片
组件布局
- 控制组件的摆放方式
- 三种布局:
- pack: 按照方位布局
- place: 按照坐标布局
- grid: 网格布局
- pack布局
- 最简单,代码量最少,挨个摆放,默认从上到下,系统自动设置
- 通用使用方式为:组件对象.pack(设置...)
- side:停靠方位,可选值为LEFT,TOP,RIGHT,BOTTOM
- fill:填充方式,X, Y, BOTH, NONE
- expande: YES/NO
- anchor: N,E,S,W, CENTER
- ipadx: x方向的内边距
- ipady: y
- padx: x方向外边界
- pady: y…
- grid布局
- 通过使用方式:组件对象.grid(设置...)
- 利用row,column编号,都是从0开始
- sticky:N,E,S,W表示上下左右,用来决定组件从那个方向开始
- 支持ipadx, padx等参数,跟pack函数含义一样
- 支持rowspan, columnspan, 表示跨行,跨列数量
- place布局
- 明确方位的摆放
- 相对位置布局,随意改变窗口大小会导致混乱
- 使用place函数,分为绝对布局和相对布局
- 绝对布局使用x,y参数
- 相对布局使用relx,rely,relheight,relwidth
---窗口居中显示---
import tkinter
win = tkinter.Tk()
# 得到屏幕宽度
sw = win.winfo_screenwidth()
# 得到屏幕高度
sh = win.winfo_screenheight()
# 窗口宽高为100
ww = 500
wh = 100
x = (sw-ww) / 2
# 50为任务栏高度
y = (sh-wh-50) / 2
win.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
win.mainloop()
---pack布局案例---
import tkinter
baseframe = tkinter.Tk()
# 以下所有代码都是创建一一个组件,然后布局
btn1 = tkinter.Button(baseframe, text='A')
btn1.pack(side=tkinter.LEFT, expand=tkinter.YES, fill=tkinter.Y)
btn2 = tkinter.Button(baseframe, text='B')
btn2.pack(side=tkinter.TOP, expand=tkinter.YES, fill=tkinter.BOTH)
btn2 = tkinter.Button(baseframe, text='C')
btn2.pack(side=tkinter.RIGHT, expand=tkinter.YES, fill=tkinter.NONE, anchor=tkinter.NE)
btn2 = tkinter.Button(baseframe, text='D')
btn2.pack(side=tkinter.LEFT, expand=tkinter.NO, fill=tkinter.Y)
btn2 = tkinter.Button(baseframe, text='E')
btn2.pack(side=tkinter.TOP, expand=tkinter.NO, fill=tkinter.BOTH)
btn2 = tkinter.Button(baseframe, text='F')
btn2.pack(side=tkinter.BOTTOM, expand=tkinter.YES)
---账号登录实例---
import tkinter
def register(event):
user = userNameEntry.get()
pwd = pwdEntry.get()
t1 = len(user)
t2 = len(pwd)
if user == "root" and pwd == "123456":
statusLabel['text'] = "登录成功"
else:
statusLabel['text'] = "用户名或密码错误"
userNameEntry.delete(0, t1)
pwdEntry.delete(0,t2)
psd = tkinter.Tk()
userName = tkinter.Label(psd, text="用户名")
userName.grid(row=0, sticky=tkinter.W)
userNameEntry = tkinter.Entry(psd)
userNameEntry.grid(row=0, column=1, sticky=tkinter.E)
pwd = tkinter.Label(psd, text="密码")
pwd.grid(row=1, column=0, sticky=tkinter.W)
# 将输入内容进行加密
pwdEntry = tkinter.Entry(psd)
pwdEntry['show'] = '*'
pwdEntry.grid(row=1, column=1, sticky=tkinter.E)
loginBtn = tkinter.Button(psd, text="登录", command=register)
loginBtn.grid(row=2, column=1, sticky=tkinter.E)
# 绑定按'Enter'触发事件
psd.bind('', register)
statusLabel = tkinter.Label(psd, text='')
statusLabel.grid(row=3)
psd.mainloop()
显示图片
- tkinter.PhotoImage(file='图片路径')
- 导入其他类型的图片
- 导入模块:from PIL import Image, ImageTk
- 导入图片,设置图片大小:img = Image.open('xx.jpg').resize((200, 200))
- 加载进tkinter画布:photo = ImageTk.PhotoImage(img)
---背景图实例---
import tkinter as tk
from PIL import Image, ImageTk
baseframe = tk.Tk()
baseframe.wm_title("背景图实例")
# 设置背景图
img = Image.open('20.jpg').resize((200, 200))
photo = ImageTk.PhotoImage(img)
# 添加其他内容
theLabel = tk.Label(baseframe, text="我是内容,n请你阅读",
justify=tk.LEFT,
image=photo,
compound=tk.CENTER,
font=("华文行楷", 20),
fg="white")
theLabel.pack()
tk.mainloop()
消息机制
- 消息的传递机制
- 自动发出事件/消息
- 消息有系统负责发送到队列
- 由相关组件进行绑定/设置
- 后端自动选择感兴趣的事件并做出相应反应
- 消息格式
- <[modifier-]-typer-[-detail]>
- : Button表示一个按钮事件,1代表鼠标左键,2代表中键, 3代表右键
- : 键盘A键位
- : 同时按下Control, Shift, A三个键位
- : F1键位
- 全部键位对应名称
---点击事件实例---
import tkinter
def baseLabel(event):
global baseframe
lb = tkinter.Label(baseframe, text="你点我干嘛...")
lb.pack()
# 画出程序的总框架
baseframe = tkinter.Tk()
baseframe.wm_title("点击事件实例")
# label绑定相应的消息和处理函数
lb = tkinter.Label(baseframe, text="模拟按钮")
# 自动获取左键点击,并启动相应的处理函数baseLabel
lb.bind("", baseLabel)
lb.pack()
baseframe.mainloop()
Tkinter的绑定
- bind_all: 全局范围的绑定,默认的是全局快捷键,比如F1是帮助文档
- bind_class:接受三个参数,第一个是类名,第二个是事件,第三个是操作
- bind:单独对某一个实例绑定
- unbind:解绑,需要一个参数,即你要解绑的那个事件
菜单
- 普通菜单
- 第一个Menu类定义的是parent(父类菜单)
- add_ command: 添加菜单项,如果菜单是顶层菜单,则从左向右添加,否则就是下拉菜单
- label: 指定菜单项名称
- command: 点击后相应的调用函数
- acceletor: 快捷键
- underline: 制定是否菜单信息下有横线
- menu: 属性制定使用哪-一个作为顶级菜单
---普通菜单实例---
import tkinter
baseframe = tkinter.Tk()
baseframe.wm_title("普通菜单实例")
menubar = tkinter.Menu(baseframe)
for item in ['菜单1', '菜单2', '菜单3', '菜单4']:
menubar.add_command(label=item)
baseframe['menu'] = menubar
baseframe.mainloop()
- 级联菜单
- add_ cascade: 级联菜单,作用是引出后面的菜单
- add_ cascade的menu属性: 指明把菜单级联到哪个菜单上
- label: 需要显示的名称
- 级联菜单的创建过程:
- 建立menu实例 -> add_command -> add_cascade
---级联菜单实例---
import tkinter
baseframe = tkinter.Tk()
baseframe.wm_title("级联菜单实例")
menubar = tkinter.Menu(baseframe)
e_menu = tkinter.Menu(menubar)
for item in ['Copy', 'Past', 'Cut']:
e_menu.add_command(label=item)
menubar.add_cascade(label='File')
menubar.add_cascade(label='Edit', menu=e_menu)
menubar.add_cascade (label= 'about')
baseframe['menu'] = menubar
baseframe.mainloop()
- 弹出式菜单
- 弹出菜单也叫上下文菜单
- 实现的大致思路
- 建立菜单并向菜单添加各种功能
- 监听鼠标右键
- 如果右键点击,则根据位置判断弹出
- 调用menu的pop方法
- add_separator: 添加分隔符
---弹出式菜单实例---
import tkinter
def makeLabel():
global baseframe
tkinter.Label(baseframe, text="PHP是最好的编程语言,我用Python").pack()
baseframe = tkinter.Tk()
baseframe.wm_title("弹出式菜单实例")
menubar = tkinter.Menu(baseframe)
for x in ['麻辣香菇', '气锅鸡', '东坡肘子']:
menubar.add_separator()
menubar.add_command(label=x)
menubar.add_command(label='重庆火锅', command=makeLabel)
# 事件处理函数:一定要至少有一个参数,且第一个参数表示的是系统事件
def pop(event):
# 注意使用event.x 和event.x root的区别
menubar.post(event.x_root, event.y_root)
# 鼠标右键点击事件
baseframe.bind("", pop)
baseframe.mainloop()
canvas-画布
- 画布: 可以自由的在上面绘制图形的一个小舞台
- 在画布上绘制对象,通常用create_xxXX, xxxx=对象类型,例如line, rectangle
- 画布的作用是把一定组件画到画布上显示出来
- 画布所支持的组件:
- arc
- bitmap
- image(BitmapImage, PhotoImage)
- line
- oval
- polygon
- rectangle
- text
- winodw(组件)
- 每次调用create_xxx都会返回一个创建的组件的ID,同时也可以用tag属性指定其标签
- 通过调用canvas.move实现一个一次性动作
---画布实例---
import tkinter
baseframe = tkinter.Tk()
baseframe.wm_title("画布实例")
cvs = tkinter.Canvas(baseframe, width=300, height=200)
cvs.pack()
# 一条线需要两个点指明起始
# 参数数字的单位是px
cvs.create_line(23,23, 190,234)
cvs.create_text(56,67, text="I LOVE PYTHON")
baseframe.mainloop()
---五角星实例---
import tkinter
import math as m
baseframe = tkinter.Tk()
baseframe.wm_title("五角星实例")
w = tkinter.Canvas(baseframe, width=300, height=300, background="gray")
w.pack()
center_x = 150
center_y = 150
r=150
points = [
#左上点
center_x - int(r * m.sin(2 * m.pi / 5)),
center_y - int(r * m.cos(2 * m.pi / 5)),
#右上点
center_x + int(r * m.sin(2 * m.pi / 5)),
center_y - int(r * m.cos(2 * m.pi / 5)),
#左下点
center_x - int(r * m.sin( m.pi / 5)),
center_y + int(r * m.cos( m.pi / 5)),
#顶点
center_x,
center_y - r,
#右下点
center_x + int(r * m.sin(m.pi / 5)),
center_y + int(r * m.cos(m.pi / 5)),
]
#创建一个多边形
w.create_polygon(points, outline= "green", fill="yellow")
w.create_text(150,150, text="五角星")
baseframe.mainloop()
---动画实例---
import tkinter
baseframe = tkinter.Tk()
baseframe.wm_title("动画实例")
def btnClick(event):
global w
w.move(id_ball, 12,5)
w.move("fall", 0,5)
w = tkinter.Canvas(baseframe, width=500, height=400)
w.pack()
w.bind("", btnClick)
#创建组件后返回id
id_ball = w.create_oval(20,20,50,50, fill="green")
#创建组件使用tag属性
w.create_text(123,56, fill="red", text="ILovePython", tag="fall")
#创建的时候如果没有指定tag可以利用addtag_ wi thtag添加
#同类函数还有addtag_ all, addtag_ above, addtag_ xxx等等
id_rectangle = w.create_rectangle(56,78,173,110, fill="gray")
w.addtag_withtag("fall", id_rectangle)
baseframe.mainloop()