ptrhon GUI编程
GUI程序步骤
从tkinter中加载组件类
- from tkinter import *
创建组件类实例
- Label(父组件对象, 标签配置选项),例如wedget = Label(None,text=’wy’):默认顶层窗口,显示文本
- 另外组件的配置方法:wedget[‘text’]=’wy’;wedget.config(text=’wy’)
在父组件中打包该实例.wedget.pack(),调用打包几何管理器,安排组件在容器中的位置,返回空.
- 安排组件位置依据:
- 被pack()的顺序.窗口收缩时,先打包的组件最后被裁切
- 边的选项设置
- side参数:父组件边中的位置,例如TOP,LEFT
- expand参数:YES为组件扩展空间
- fill参数:拉伸组件充满空间.Y垂直,X水平,BOTH都拉伸
- anchor参数:分配空间大于组件需要的显示空间时,定位,默认CENTER,有N,E,W,S,NE,NW,SE,SW等方位
- pack_forget():擦除(取消映射,隐藏)一个绘制的组件
- 安排组件位置依据:
调用主循环,显示窗口,开始事件循环.
- wedget.mainloop():可作为函数和方法
基本概念
根窗口:tkinter.Tk()返回的对象,GUI程序中可以有多个顶层窗口,但是其中只能有一个是根窗口(可以手动创建多个根窗口)默认都会创建TK作为父窗口.
顶层窗口:在应用中独立显示窗口.Toplevell或TK.
控件:GUI 组件,控件可以独立存在,也可以作为容器存在。如果一个控件包含其他控件,就可以将其认为是那些控件的父控件。相应地,如果一个控件被其他控件包含,则将其认为是那个控件的子控件。
事件:控件的一些相关的行为.
回调:GUI 对事件的响应.
事件驱动处理:一个 GUI 应用从开始到结束就是通过整套事件体系来驱动的。
布局管理器:帮助控件集进行定位.三种:
- place:直接提供控件的大小和摆放位置,然后管理器就会将其摆放好。会加重编程开发者的负担.
- pack:会把控件填充到正确的位置(即指定的父控件中),然后对于之后的每个控件,会去寻找剩余的空间进行填充。(主要)
- grid:基于网格坐标,使用 Grid 来指定 GUI 控件的放置。Grid 会在它们的网格位置上渲染 GUI 应用中的每个对象
复合组件:Dialog,ScrolledText, OptionMenu
回调安排:组件的after,wait,update方法
控件
控件 | 描述 |
---|---|
Button | 与Label类似,但提供额外的功能,如鼠标悬浮、按下、释放以及键盘活动/事件 |
BitmapImage | 图像组件,用于在其他组件上显示位图 |
Canvas | 提供绘制形状的功能(线段、椭圆、多边形、矩形),可以包含图像或位图 |
Checkbutton | 多选框,可以勾选其中的任意个(与HTML的checkbox输入类似) |
Entry | 单行文本框 |
Frame | 包含其他控件的纯容器 |
Label | 用于包含文本或图像 |
LabelFrame | 标签和框架的组合,拥有额外的标签属性 |
Listbox | 给用户显示一个选项列表来进行选择 |
Menu | 按下Menubutton后弹出的选项列表,用户可以从中选择 |
Menubutton | 用于包含菜单(下拉、级联等) |
Message | 消息。与Label类似,不过可以显示成多行 |
PanedWindow | 一个可以控制其他控件在其中摆放的容器控件 |
PhotoImage | 图像组件,用于在其他组件上显示全彩色图像 |
Radiobutton | 单选按钮 |
Scale | 线性“滑块”控件,根据已设定的起始值和终止值,给出当前设定的精确值 |
Scrollbar | 为Text、Canvas、Listbox、Enter等支持的控件提供滚动功能 |
Spinbox | Entry和Button的组合,允许对值进行调整 |
Text | 多行文本框,用于收集(或显示)用户输入的文本(与HTML的textarea类似) |
Toplevel,TK | 与Frame类似,不过它提供了一个单独的窗口容器 |
窗口
方法:
- title(‘标题’):设置窗口标题
- quit():结束mainloop事件循环呼叫,退出程序
- destroy():关闭一个窗口(及其子窗口)或删除一个组件
- protocol(‘WM_DELETE_WINDOW’, lambda:None):忽略关闭,设置x的功能
- iconbitmap(‘图标或位图文件’):改变顶层窗口的图标
- maxsize():获取最大化窗口的大小(宽度,高度)
- geometry(“宽x高+离屏幕左边界距离+离屏幕上边界距离”).x是小写字母x,不是乘号
- iconify():隐藏窗口,显示图标,像最小化
- withdraw():隐藏窗口
- deiconify():重新创建已隐藏或删除的窗口
- state():查看或改变窗口状态. normal, icon,iconic (see wm_iconwindow), withdrawn, or zoomed (全屏,只在Windows上).
- bell():系统的声音接口
- flash():使组件瞬时闪动,快速变换颜色
参数配置选项
- master或第一个参数:父控件,不传入或传入None都默认Tk
- text:显示文本
- command:注册处理器,记录组件事件发生调用的行为,任何可调用对象(函数,lambda,类方法,可调用类等)
- 不会接到参数,可以通过全局变量,类实例属性,间接层提供额外属性
- 如果直接调用一个有参数的函数,会在创建时运行,需要间接层(放入一个无参的函数或lambda)
- state:状态.DISABLED(禁用),NORMAL(正常),READONLY(只读)
配置组件外观外观:
- bg:背景颜色,颜色名称或十六进制字符串(“#ff0000”)
- fg:前景颜色,文本颜色
- font:传入(字体系列,大小,类型)三元组.字体系列有Times,Courier,Helvetica等,类型有:normal(正常),bold(粗体),romam(罗马),italc(斜体),underline(下划线),overstrike(加粗)等
- height:高度
- width:宽度
- bd:边框宽度
- relief:边框类型,FLAT(扁平),SUNKEN(凹陷),RAISED(凸起),GROOVE(凹槽),SOLID(加粗),RIDGE(脊柱)
- cursor:鼠标经过时指针外观.crdss(十字),pencil(铅笔),hand2(手形2)
- padx,pady:留白,周围添加额外空间
对话框
通过脚本弹出窗口,提供或要求额外的信息.分为模态(会阻止其他界面,直至被关闭)和非模态(不干扰其他界面)
通用对话框:
- 都是模态
- 位于kinter.messagebox中,第一个参数是标题,第二个参数是显示文字:askokcancel(返回True和False), askquestion(返回yes和no), askretrycancel(返回True和False), askyesno(返回True和False), askyesnocancel(返回True和False和不返回), showerror(返回0k), showinfo(返回0k), showwarning(返回0k)
- tkinter.filedialog中,文件打开和保存对话框,返回相应的目录路径,文件路径或文件对象:’askdirectory’, ‘askopenfile’, ‘askopenfilename’, ‘askopenfilenames’, ‘askopenfiles’, ‘asksaveasfile’, ‘asksaveasfilename’.可以传入:filetypes(用于选择文件的名称模式),initialdir(起始目录),initialfile(“文件名”),title(对话框窗口),defautextension(默认选择),parent(显示为嵌入式子级)
- tkinter.colorchooser中askcolor,调色板选择颜色,会返回RGB颜色值三元组和十六进制字符串.
- tkinter.simpledialog中,有输入框,返回之前自动检测,返回相应的对象类型或None:’askfloat’, ‘askinteger’, ‘askstring’
旧式dialog模块(tkinter.dialog中Dialog):
- 模态
- 参数:title(标题),text(显示文字),bitmap(图标),default=0,string=(‘按钮1’,’按钮2’)定义按钮,返回按钮索引(从左边零开始)
自定义对话框:
- 创建Toplevel弹出窗口,非模态
- 使成为模态:focus_set()(获得输入焦点),grab_set()(打开的时候,禁用其他窗口),wait_window()(在销毁之前,继续等待)
绑定事件
组件.bind(‘事件’,回调函数):回调函数接受一个事件对象参数
事件:
<Button-1>
:单击鼠标左键<Button-2>,<Button-3>
:鼠标中键(没有可以同时点击左键和右键)和右键的单击事件<ButtonPress>,<ButtonRelease>
:按下和松开按钮<Double-1>
:双击鼠标左键<KeyPress>
:键盘上单键的按下,将按下的键以ASCLL字符串(event.char)传给回调函数
- 可以类似更具体
<Return>,<Up>,<Escape>,<BackSpace>,<Top>,<Down>,<Left>,<Right>
:捕捉更具体的按键,返回/回车键,向上箭头键等<B1-Motion>
:捕捉按住一个鼠标左键时鼠标的移动,返回当前的x/y坐标(event.x和event.y)<Motion>
:鼠标指标移动<Enter>,<Leave>
:鼠标的进入和退出(对自动高亮组件有效)<Configure>
:窗口大小和位置的改变(event.width和event.height会给出新窗口的大小)<Destory>
:销毁窗口组件时<FocusIn>,<FocusOut>
:获得和失去焦点<Map>,<Unmap>
:窗口打开和最小化时<<Paste Text>>
:可以指定一个或多个事件序列的选择
event:
- event.x和event.y可以获得事件发生时的坐标
- 其他:’char’, ‘delta’, ‘height’, ‘keycode’, ‘keysym’, ‘keysym_num’, ‘num’, ‘send_event’, ‘serial’, ‘state’, ‘time’, ‘type’, ‘widget’, ‘width’, ‘x’, ‘x_root’, ‘y’, ‘y_root’
Message和Entry组件
Text功能组件的子集,允许显示输入简单文本
tkinter.Message:显示文本
tkinter.Entry:输入框.
- insert(0,’设置文本’):设置文本,第一个参数是文本的插入位置,第二个参数是插入的文本
- delete(0,END):删除全部文本
- get():获取文本
tkinter连接变量
StringVar, IntVar, DoubleVar, BooleanVar,一般通过组件的variable参数关联tkinter变量
绑定变量:
ent = Entry()
var = StringVar()
ent.config(textvariable=var)
改变和获取变量的值:
var.set('text')
value = var.get()
Checkbutton,Radiobutton和Scale
Checkbutton(复选按钮):
- 被选中时,其关联的tkinter变量为1,否则为0
- 每个按钮关联不同的tkinter变量
Radiobutton(单选按钮):
- value:按钮被选中时关联变量的值,通常不同
- 按钮关联同一个tkinter变量
- 当按钮被选中时共享的tkinter变量的值改变为按钮的值
Scale(滑动条):
- 有get()和set()方法可以直接设置和获取值
- 移动时,标尺值会传给回调函数
- 参数:from_和to(标尺范围的最小值和最大值),tickinterval(标尺旁边的单位刻度间距),resolution(拖动或点击一次,移动的间距),showvalue(显示或隐藏当前值,默认YES)
- tkinter变量同步化标尺(使几个标尺同步移动)
图像
创建独立的PhotoImage和BitmapImage(.xbm位图文件)对象,其他组件通过image的属性设置附加图像对象
igm = PhotoImage(file="文件路径名") # 支持gif(不动),ppm,pgm等图形文件
but = Button(None,image=igm)
but.image = igm # 显示的引用图像对象,防止被垃圾回收
but.pack()
通过canvas组件
can = Canvas(win)
can.pack(fill=BOTH)
can.creat_image(2,2,image=igm,anchor=NW)
使用pillow查看和处理图像
pip install pillow
官网:https://pypi.org/project/Pillow/
可以用PIL模块中的ImageTk中的PhotoImage和BitmapImage对象支持更多的格式
from tkinter import *
from PIL import ImageTk
win = Tk()
photoimg = ImageTk.PhotoImage(file="文件名") # 需要先创建有组件对象才能成功
Image模块:
from PIL import Image
im = Image.open("hopper.ppm") # 打开图片,Image对象
im.format # 图片格式
im.size # 图片宽度和高度(以像素为单位)的2元组
im.show() # 显示图像
im.thumbnail((128,128)) # 创建JPEG缩略图,保存时指定JPEG
im.save() # 保存图像,可以第二个参数指定格式
im.mode # 模式,灰度图像的“L”(亮度),真彩色图像的“RGB”和印前图像的“CMYK”
菜单
顶层窗口菜单
- 创建顶层Menu为窗口的子组件,并将窗口的menu属性设置为顶层Menu对象
- 设置子菜单对象:创建父Menu对象的子组件Menu,在父Menu的add_cascade()方法中指定
- 设置子选项:使用add_command()方法
示例:
win = Tk()
top = Menu(win)
win.config(menu=top)
file = Menu(top)
top.add_cascade(label='File',menu=file,underline=0) #add_cascade()生成子菜单
file.add_command(label='New',command=(lambda:None),underline=0) # add_command()生成子选项
file.add_command(label='Open',command=(lambda:None),underline=0) # underline设置快捷键
file.add_separator() # 生成选项之间的分割线
submenu = Menu(file,tearoff=False) # tearoff消除菜单选项顶部的虚线
file.add_cascade(lable='Submenu',menu=submenu,underline=0)
基于Menubutton的菜单和OptionMenu
将Menubutton组件填充在Frame容器中,并将Menu组件与Menubutton相关联
示例:
win = Tk()
frame = Frame(win)
frame.pack(side=TOP,fill=x)
#核心
fbutton = Menubutton(frame,text='file',underline=0)
fbutton.pack(side=LEFT)
file = Menu(fbutton)
fbutton.config(menu=file)
file.add_command(label='New',command=(lambda:None),underline=0)
OptionMenu:通过tkinter变量的值获取选中项
win = Tk()
#核心
var = StringVar()
opt = OptionMenu(win,var,'spam','eggs','toast') # 变量的可选值,按钮显示
opt.pack(fill=X)
var.set('spam') # 设置变量的值,默认选择
Listbox和Scrollbar
win = Tk()
#核心
sbar = Scrollbar(win) # 生成滚动条对象
list = Listbox(win, relief=SUNKEN) # 生成列表框对象
sbar.config(command=list.yview) # 按比例调节列表框显示,横向变为x,加上orient='horizontal'配置选项
list.config(yscrollcommand=sbar.set) # yscrallcommand选项有两个记录,可以按比例调节滚动条
sbar.pack(side=RIGHT,fill=Y)
list.pack(side=LEFT,expand=YES,fill=BOTH)
# Listbox方法
list.insert(END,"aaa") # 插入选项,从0开始索引,END或"end"表示末尾,ACTIVE或"active"表示选中的列表项
for i in range(20):
list.insert(i,i)
list.config(selectmode=SINGLE,setgrid=1) # 设置模式,有SINGLE(单选),BROWSE(默认,单选且允许拖拉选项),MULTIPLE(多选,单击一个条目会触发其状态不影响其他条目),EXTENDED(多选)
list.bind('<Double-1>',aa) # 绑定事件
def aa(event):
label = list.get("active")) # 获得选中项的值,还有active, anchor, end, @x,y, or a number
print(label)
Text组件
text = Text()
#索引定位
text.insert('1.0', text) # 插入,第一个参数是绝对位置索引,行从第1行开始,列从第0列开始
text.delete('1.0',END) # 第一个参数是起始删除位置,第二个参数是结束删除位置
text.get('1.0', END+'-1c') # END指最后一个字符之后的位置,'-1c'上一个字符,'+1c'下一个字符,'+2l'前面一行,'-2l'后面一行,Lineend行末,wordstart词首
#标志定位,两个字符间位置的象征性名称
text.mark_set(INSERT, '1.0') # INSERT预定义标签,表示插入光标的位置
text.mark_set('linetwo', '2.0') # 创建标志,第一个参数标志名称,第二个参数标志位置
text.mark_unset('linetwo') # 通过标志名称删除标志
#标签定位,与一个或多个子字符串相关的名称
text.tag_add('alltext','1.0',END) # 创建标签,标签名称,开始和结束位置内容添加到标签
text.tag_add(SEL, index1,index2) # SEL预定义标签,表示选中文本,索引范围内的文本会被选中
text.get('alltext.first', 'alltext.last') # 标签的.first和.last分别获取标签开始和结束的索引
text.tag_remove(SEL, '1.0', END) # 从某一文本范围内删除所有标签
text.tag_delete() # 删除标签本身
text.search(target, INSERT, END) # 搜索字符串,返回第一次出现的起始索引位置
text.see(INSERT) #滚动显示
text.tag_config('demo',background='purple') # 设置标签属性,第一个参数标签名称
text.tag_bind('demo','<Double-1>',hello) # 绑定标签事件,参数:标签名称,事件,回调函数
#剪贴版
clipboard_clear() #清空剪切板
clipboard_append(text) # 存入剪切板
text = selection_get(selection='CLIPBOARD') #获取剪切板内容
#在索引中内嵌其他组件或图片
text.window_create(END, window=but) # 第一个参数索引,第二个参数组件
text.image_create(END, image=img) # 第一个参数索引,第二个参数图像对象
Canvas
坐标:
- 画布左上角为(0,0),向下向右增加,默认像素点为单位
构建对象:
- ‘create_arc’(扇形,根据矩形对角线坐标),’create_line’(直线), ‘create_oval’(圆形,根据矩形对角线坐标), ‘create_rectangle’(矩形):参数两个坐标
- ‘create_polygon’(直线构成的形状):任意一组坐标参数
- ‘create_text’, ‘create_window’,’create_bitmap’, ‘create_image’:坐标限定左上角,相应的关键字参数指定对象
- 可以有颜色,边框等一般设置,每个对象也有自己独特的设置
对象标识及其操作:
- 创建对象时会返回id,用于标识对象
- move(idortag,偏移x,偏移y):移动,delete(idortag)删除,tkraise(idortag)移到前端,lower(idortag):降低层次,itemconfig(idortag,fill=’red’):属性设置
对象标签:
- 将一组对象关联起来操作,同一个对象可以有不同的标签
- 创建的时候tag选项中设置
- addtag_withtag(tag,idortag)
- 预定义标签:all(所有对象),current(鼠标光标指向的对象)
- find_类方法查找对象,postscrip方法可在postscrip文件中保存画布
滚动画布:
- 画布的wideh和height设置的是可查看区域大小,给定左上角和右下角坐标,通过scrollregion选项设置全局大小,默认为查看大小,不设置,滚动条就失去意义
- 事件对象返回的坐标值是查看区域的坐标值,需要映射到画布坐标,将其传递给canvasx和canvasy的画布方法
画布事件:
- 除了普通的事件绑定,还支持tag_bind方法
网格
win = Tk()
lab = Label(win, text='lab',width=25)
ent = Entry(win,width=50)
lab.grid(row=0,column=0,sticky=NSEW) # 通过行row和列column布局,sticky设置在分配的空间中固定于一边或多边
lab.grid_forget() # 隐藏组件
ent.grid(row=0,column=1,sticky=NSEW)
win.rowconfig(1,weight=1) # 对每行和每列设置权重,扩展比例,默认0不扩展
win.columnconfig(0,weight=1)
win.columnconfig(1,weight=1)
Label(win.text='more_lab',columnspan=2) # columnspan:横跨多列,rowspan:横跨多行
时间工具,线程和动画
计时器函数:
widget.after(milliseconds, function, *args):在若干毫秒时间之后,调用一次函数.返回一个id.
widget.after(milliseconds):使程序终止若干毫秒.
widget.after_idle(function, *args):当没有挂起的事件需要处理,GUI空闲的时候,调用一次函数
widget.after_cancel(id):撤销一个挂起的after回调事件
widget.update():强制tkinter处理事件队列中所有挂起的事件更新.
widget.update_idletasks():处理一切挂起的空闲事件
_tkinter.createfilehandler(file, mask, function):函数在文件状态发生改变的时候被调用
widget.wait_variable(var),widget.wait_window(win),widget.wait_visibility(win):在tkinter变量的值发生变化,窗口被销毁或变得可见时,终止调用者.
动画效果:
- 三种基本方法:
- 休眠time.sleep(),需要canvas.update,会被阻塞,不并行
- 计时器,允许并行,不需要canvas.update,不需要休眠,不会被阻塞
- 线程+time.sleep(),有可能存在线程安全问题