python-GUI之Tkinter

GUI介绍

  • GraphicalUserInterface,简称GUI–图形化界面
    • python的GUI: Tkinter, wxPython, PyQt
  • TKinter:
    • Python标准库,绑定的是TK GUI工具集,简单易用
  • PyGTK:
    • Tkinter的替代品
  • wxPython:
    • 跨平台的Python GUI,开源免费
  • 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()
---窗口居中显示---
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()

组件的大致使用步骤

  1. 创建总面板
  2. 创建面板上的各种组件
    1. 指定组件的父组件,即依附关系
    2. 利用相应的属性对组件进行设置
    3. 给组件安排布局
  3. 同步骤2相似,创建好多个组件
  4. 最后,启动总面板的消息循环
---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: 按照方位布局,即按添加顺序排列组件
      • grid: 网格布局,即按行列形式排列组件
      • place: 按照坐标布局,能够实现自定义排列组件
      • 注意:不要在同一个父组件中同时使用 pack 和 grid
    • pack布局
      • 最简单,代码量最少,挨个摆放,默认从上到下,系统自动设置(适用于少量组件简单布局)
      • 基本格式:组件对象.pack()
        • side:停靠方位,可选值为LEFT,TOP,RIGHT,BOTTOM
        • fill: 填充方式X(水平), Y(垂直), BOTH(水平和垂直), NONE(默认)
        • expande: YES/NO
        • anchor: N,E,S,W, CENTER
        • ipadx: 水平方向的内边距
        • ipady: 垂直方向的内边距
        • padx: 水平方向外边距
        • pady: 垂直方向外边距
    • grid布局
      • 把整个窗口看成一个网格,通过行和列来指定位置,适用于对话框一类的布局
      • 基本格式:组件对象.grid(row,column...)
        • 利用row,column编号,即行号列号
        • stickyN,E,S,W表示上下左右,用来决定组件的对齐方向
        • ipadx: 水平方向的内边距
        • ipady: 垂直方向的内边距
        • padx: 水平方向外边距
        • pady: 垂直方向外边距
        • rowspan: 表示跨行,跨行数量
        • columnspan: 表示跨列,跨列数量
    • place布局(不常用)
      • 虽然能够实现自定义排列组件,但使用起来过于复杂,还容易出现重叠
      • 使用place布局,分为绝对布局相对布局
        - 相对布局使用relx,rely,relheight,relwidth
        - 绝对布局使用x,y参数
---pack基本布局案例---
import tkinter as tk 

baseFrame = tk.Tk()
tk.Label(baseFrame, text="Red", bg="red", fg="white").pack()
tk.Label(baseFrame, text="Blue", bg="blue", fg="white").pack()
tk.Label(baseFrame, text="Green", bg="green", fg="white").pack()
tk.Label(baseFrame, text="Yellow", bg="yellow", fg="black").pack()
---账号登录(grid)实例---
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('<Return>', register)

statusLabel = tkinter.Label(psd, text='')
statusLabel.grid(row=3)
psd.mainloop()

三种标准对话框

提示消息对话框
  • 导入模块:from tkinter import messagebox
  • 警告对话框
    • .showinfo():蓝感叹号警告
      • 选项:确定
      • 返回值:ok
    • .showwarning():黄三角警告
      • 选项:确定
      • 返回值:ok
    • .askretrycancel():黄三角警告
      • 选项:重试取消
      • 返回值:TureFlase
  • 错误对话框
    • .showerror():错误
      • 选项:确定
      • 返回值:ok
  • 询问对话框
    • .askquestion():询问
      • 选项:
      • 返回值:yesno
    • .askokcancel():询问
      • 选项:确定取消
      • 返回值:TureFlase
    • .askyesno():询问
      • 选项:
      • 返回值:TureFlase
    • .askyesnocancel():询问
      • 选项:取消
      • 返回值:TureFlaseNone
  • 全部对话框的参数
    • 对话框类型(title, message, default, icon, parent)
      • title:对话框标题
      • message:对话框内容
      • default:设置按回车键执行的按钮CANCEL,IGNORE,OK,NO,RETRY 或 YES
      • icon:对话框图标ERROR,INFO,QUESTION 或 WARNING
      • parent:…不常用,有兴趣自行了解
---对话框实例---
from tkinter import messagebox
res = messagebox.askquestion(title='问候一下', message='您吃饭了吗?')
print(res)
文件相关对话框
  • 导入模块:from tkinter import filedialog
  • .askopenfilename():选择文件名
    • 返回值:返回文件名
  • .askdirectory():选择目录名
    • 返回值:返回目录名
  • .asksaveasfilename():保存文件
    • 返回值:返回文件名
  • 全部文件相关的参数
    • defaultextension:指定保存文件的文件后缀
    • filetypes:指定筛选下拉菜单的类型
    • initialdir:默认的打开路径
    • title:对话框的标题
    • parent:…不常用,有兴趣自行了解
  • 注意:如果用户点击了取消按钮,那么返回值是空字符串
---图片另存实例---
import tkinter as tk
from tkinter import filedialog as fd
from PIL import Image

def selectFile():
    global img,filepath
    # 选择打开什么文件,返回文件名
    filepath = fd.askopenfilename(title="选择要另存的图片")
    # 设置变量filename的值
    filename.set(filepath)
    # 打开图片
    img = Image.open(filename.get())
def outputFile():
    # 选择目录,返回目录名
    outputFilePath = fd.askdirectory(title="选择需要另存的目录")
    # 设置变量outputpath的值
    outputpath.set(outputFilePath)
def fileSave():
    # 设置保存文件,返回文件名
    extension = "." + filepath.split(".")[-1]
    filenewpath = fd.asksaveasfilename(title="设置要保存的图片名", defaultextension=extension)
    # 设置变量filenewname的值
    filenewname.set(filenewpath)
    # 设置保存图片
    img.save(str(filenewname.get()))

save_image = tk.Tk()
save_image.wm_title("保存图片")
filename = tk.StringVar()
outputpath = tk.StringVar()
filenewname = tk.StringVar()

# 构建“选择文件”这一行的标签、输入框以及启动按钮,同时我们希望当用户选择图片之后能够显示原图的基本信息
tk.Label(save_image, text='选择图片').grid(row=1, column=0, padx=5, pady=5)
tk.Entry(save_image, textvariable=filename).grid(row=1, column=1, padx=5, pady=5, ipadx=50)
tk.Button(save_image, text='打开图片', command=selectFile).grid(row=1, column=2, padx=5, pady=5)

# 构建“选择目录”这一行的标签、输入框以及启动按钮
tk.Label(save_image, text='选择目录').grid(row=2, column=0, padx=5, pady=5)
tk.Entry(save_image, textvariable=outputpath).grid(row=2, column=1, padx=5, pady=5, ipadx=50)
tk.Button(save_image, text='点击选择', command=outputFile).grid(row=2, column=2, padx=5, pady=5)

# 构建“保存文件”这一行的标签、输入框以及启动按钮
tk.Label(save_image, text='保存文件').grid(row=3, column=0, padx=5, pady=5)
tk.Entry(save_image, textvariable=filenewname).grid(row=3, column=1, padx=5, pady=5, ipadx=50)
tk.Button(save_image, text='点击保存', command=fileSave).grid(row=3, column=2, padx=5, pady=5)

save_image.mainloop()
颜色相关对话框
  • 导入模块:from tkinter import colorchooser
  • .askcolor():颜色选择器
    • 返回值:元组类型 -> (16进制颜色码, (R, G, B))
  • 颜色选择器参数
    • color:要显示的初始的颜色
    • title:颜色选择器的标题
    • parent:…不常用,有兴趣自行了解
---颜色选择器实例---
import tkinter as tk
from tkinter import colorchooser  # colorchooser() 颜色
root = tk.Tk()
def color_choose():
    # 调用windows的颜色选择器
    color_data = colorchooser.askcolor()
    print(color_data)
tk.Button(root, text='选择颜色', command=color_choose).pack()
tk.mainloop()

显示图片

  • tkinter.PhotoImage(file='图片路径')
    • 只支持gif格式的图片
  • 导入其他类型的图片
    1. 导入模块:from PIL import Image, ImageTk
    2. 导入图片,设置图片大小:img = Image.open('xx.jpg').resize((200, 200))
    3. 加载进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>: Button表示一个按钮事件,1代表鼠标左键,2代表中键, 3代表右键
      • <KeyPress-A>: 键盘A键位
      • <Control-Shift-KeyPress-A>: 同时按下Control, Shift, A三个键位
      • <F1>: 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("<Button-1>", baseLabel)
lb.pack()
baseFrame.mainloop()

Tkinter的绑定

  • bind_all: 全局范围的绑定,默认的是全局快捷键,比如F1是帮助文档
  • bind_class:接受三个参数,第一个是类名,第二个是事件,第三个是操作
  • bind:单独对某一个实例绑定
  • unbind:解绑,需要一个参数,即你要解绑的那个事件

菜单

  • 普通菜单
    • Menu()定义的是parent(父类菜单)
      • 第一个参数:需要绑定菜单的窗口对象
      • tearoff:菜单是否能被撕下(默认为True)
    • add_ command(): 添加菜单项,如果菜单是顶层菜单,则从左向右添加,否则就是下拉菜单
      • label: 指定菜单项名称
      • command: 点击后相应的调用函数
      • acceletor: 快捷键
      • underline: 制定是否菜单信息下有横线
      • menu: 属性制定使用哪-一个作为顶级菜单
---普通菜单实例---
import tkinter
baseFrame = tkinter.Tk()
baseFrame.wm_title("普通菜单实例")
menubar = tkinter.Menu(baseFrame, tearoff=False)
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()
  • 弹出式菜单
    • 弹出菜单也叫上下文菜单
    • 实现的大致思路
      1. 建立菜单并向菜单添加各种功能
      2. 监听鼠标右键
      3. 如果右键点击,则根据位置判断弹出
      4. 调用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("<Button-3>", 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("<Button-1>", 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()
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值