Event事件对象
当事件触发后,Tkinter 会自动将事件对象交给回调函数进行下步的处理,Event 对象包含了以下常用属性:
属性 | 说明 |
widget | 发生事件的是哪一个控件 |
x,y | 相对于窗口的左上角而言,当前鼠标的坐标位置 |
x_root,y_root | 相对于屏幕的左上角而言,当前鼠标的坐标位置 |
char | 用来显示所按键相对应的字符 |
keysym | 按键名,比如 Control_L 表示左边的 Ctrl 按键 |
keycode | 按键码,一个按键的数字编号,比如 Delete 按键码是107 |
num | 1/2/3中的一个,表示点击了鼠标的哪个按键,按键分为左、中、右 |
width,height | 控件的修改后的尺寸,对应着 <Configure>事件 |
type | 事件类型 |
下面看一组关于“键盘事件”的使用示例:
from tkinter import * # 定义事件函数,必须用event参数 def show_key(event): # 查看触发事件的按钮 s=event.keysym # 将其显示在按钮控件上 lb.config(text=s) root=Tk() root.config(bg='#87CEEB') root.title("艾派森") root.geometry('450x350+300+200') root.iconbitmap('favicon.ico') # 添加一个按钮控件 lb=Label(root,text='请按键',fg='blue',font=('微软雅黑',15)) # 给按钮控件绑定事件,按下任意键,然后调用事件处理函数。注意,此处需要在英文状态下进行输入 lb.bind('<Key>',show_key) # 设置按钮获取焦点 lb.focus_set() lb.pack() # 显示窗口 root.mainloop()
注意:在上述示例中,只有当 Label 控件获取焦点后才能接收键盘事件,因此在给控件绑定事件和回调函数后,需要使用 focus_set() 方法来获取焦点。
下面再看一组关于“鼠标事件”的相关示例:
# 定义事件函数 from tkinter import * def handleMotion(event): lb1['text'] = '你移动了光标的所在位置' lb2['text'] = '目前光标位置:x ='+ str(event.x)+';y='+str(event.y) print('光标当前位置',event.x,event.y) # 创建主窗口 win = Tk() win.config(bg='#87CEEB') win.title("艾派森") win.geometry('450x350+300+200') win.iconbitmap('favicon.ico') # 创建一个窗体容器frame frame = Frame (win, relief=RAISED, borderwidth=2, width=300,height=200) frame.bind('<Motion>',handleMotion) lb1 = Label(frame,text='没有任何事件触发') # 使用place进行位置布局,下一节会介绍 lb1.place (x=20,y=20) lb2 = Label(frame,text='') lb2.place (x=16,y=60) frame.pack(side=TOP) # 显示窗口 win.mainloop()
布局管理器(pack,grid,place)
当我们在开发一个 GUI 程序的时候,布局管理发挥着非常重要的作用,它指的是通过管理控件在窗口中的位置(排版),从而实现对窗口和控件布局的目的。
一个优秀的图形用户界面,更像是艺术家的作品,它会给用户非常良好的感官体验,因此布局管理不单单是枯燥的程序代码,更需要以“美”的角度去审视每一个细节,这才是学习布局管理的“不二法门”。Tkinter 提供了一系列布局管理的方法和容器控件,通过对这些内容的学习,您将掌握如何使用不同的方法完成界面布局。
Tkinter 提供了三种常用的布局管理器,分别是 pack()、grid() 以及 place(),如下表所示:
方法 | 说明 |
pack() | 按照控件的添加顺序其进行排列,遗憾的是此方法灵活性较差 |
grid() | 以行和列(网格)形式对控件进行排列,此种方法使用起来较为灵活 |
place() | 可以指定组件大小以及摆放位置,三个方法中最为灵活的布局方法 |
上述三种方法适用于 Tkinter 中的所有控件,在讲解前面内容时,对其中一些方法已经做了相关的介绍,比如 pack() 和 grid()。在这里会对上述三个方法的应用场景做更为详细的介绍。
pack()
pack() 是一种较为简单的布局方法,在不使用任何参数的情况下,它会将控件以添加时的先后顺序,自上而下,一行一行的进行排列,并且默认居中显示。pack() 方法的常用参数如下所示:
属性 | 说明 |
anchor | 组件在窗口中的对齐方式,有 9 个方位参数值,比如"n"/"w"/"s"/"e"/"ne",以及 "center" 等(这里的 e w s n分别代表,东西南北) |
expand | 是否可扩展窗口,参数值为 True(扩展)或者 False(不扩展),默认为 False,若设置为 True,则控件的位置始终位于窗口的中央位置 |
fill | 参数值为 X/Y/BOTH/NONE,表示允许控件在水平/垂直/同时在两个方向上进行拉伸,比如当 fill = X 时,控件会占满水平方向上的所有剩余的空间。 |
ipadx,ipady | 需要与 fill 参数值共同使用,表示组件与内容和组件边框的距离(内边距),比如文本内容和组件边框的距离,单位为像素(p),或者厘米(c)、英寸(i) |
padx,pady | 用于控制组件之间的上下、左右的距离(外边距),单位为像素(p),或者厘米(c)、英寸(i) |
side | 组件放置在窗口的哪个位置上,参数值 'top','bottom','left','right'。注意,单词小写时需要使用字符串格式,若为大写单词则不必使用字符串格式 |
下面看一组简单的使用示例:
from tkinter import * win = Tk() win.title("艾派森") win.geometry('450x300+300+300') win.iconbitmap('favicon.ico') lb_red = Label(win,text="红色",bg="Red",fg='#ffffff',relief=GROOVE) # 默认以top方式放置 lb_red.pack() lb_blue = Label(win,text="蓝色",bg="blue",fg='#ffffff',relief=GROOVE) # 沿着水平方向填充,使用 pady 控制蓝色标签与其他标签的上下距离为 5 个像素 lb_blue.pack(fill=X,pady='5px') lb_green = Label(win,text="绿色",bg="green",fg='#ffffff',relief=RAISED) # 将 黄色标签所在区域都填充为黄色,当使用 fill 参数时,必须设置 expand = 1,否则不能生效 lb_green.pack(side=LEFT,expand=1,fill = BOTH) win.mainloop()
grid()
grid() 函数是一种基于网格式的布局管理方法,相当于把窗口看成了一张由行和列组成的表格。当使用该 grid 函数进行布局的时,表格内的每个单元格都可以放置一个控件。,从而实现对界面的布局管理。
注意:这里的所说的“表格”是虚拟出来,目的是便于大家理解,其实窗体并不会因为使用了 gird() 函数,而增加一个表格。
grid() 函数的常用参数如下所示:
属性 | 说明 |
column | 控件位于表格中的第几列,窗体最左边的为起始列,默认为第 0 列 |
columnsapn | 控件实例所跨的列数,默认为 1 列,通过该参数可以合并一行中多个领近单元格。 |
ipadx,ipady | 用于控制内边距,在单元格内部,左右、上下方向上填充指定大小的空间。 |
padx,pady | 用于控制外边距,在单元格外部,左右、上下方向上填充指定大小的空间。 |
row | 控件位于表格中的第几行,窗体最上面为起始行,默认为第 0 行 |
rowspan | 控件实例所跨的行数,默认为 1 行,通过该参数可以合并一列中多个领近单元格。 |
sticky | 该属性用来设置控件位于单元格那个方位上,参数值和 anchor 相同,若不设置该参数则控件在单元格内居中 |
grid() 方法相比 pack() 方法来说要更加灵活,以网格的方式对组件进行布局管理,让整个布局显得非常简洁、优雅。如果说非要从三个布局管理器中选择一个使用的话,那么我推荐大家使用 grid() 方法。
这里有一点需要大家要特别注意,在一个程序中不能同时使用 pack() 和 grid() 方法,这两个方法只能二选一,否则程序会运行错误。
下面看一组有关 grid() 函数的简单的示例:
from tkinter import * #主窗口 win = Tk() win.config(bg='#87CEEB') win.title("艾派森") win.geometry('500x350+300+300') win.iconbitmap('favicon.ico') #在窗口内创建按钮,以表格的形式依次排列 for i in range (10): for j in range (10): Button (win, text=" (" + str(i) + ","+ str(j)+ ")",bg='#D1EEEE') .grid(row=i,column=j) # 在第5行第11列添加一个Label标签 Label(win,text="张小白",fg='blue',font=('楷体',12,'bold')).grid(row =4,column=11) #开始窗口的事件循环 win. mainloop()
当使用 grid 函数布局的时,其实就是为各个控件指定行号、列号的过程,我们不需要为每个单元格指定大小,因为 grid 会为每个单元格自动设置一个适合的尺寸。
下面通过 grid() 布局管理器制作一个简易的登录界面,代码如下所示:
import tkinter as tk from tkinter import messagebox root = tk.Tk() root.title("艾派森") root.iconbitmap('favicon.ico') root.resizable(0,0) tk.Label(root, text="用户名").grid(row=0, sticky="w") tk.Label(root, text="密码").grid(row=1, sticky="w") tk.Entry(root).grid(row=0, column=1) tk.Entry(root, show="*").grid(row=1, column=1) # 加载图片LOGO,注意这里是gif格式的图片 photo = tk.PhotoImage(file="agree.png") tk.Label(root, image=photo).grid(row=0, column=2, rowspan=2, padx='4px', pady='5px') # 编写一个简单的回调函数 def login(): messagebox.showinfo('恭喜你发现了宝藏文章!') # 使用grid()函数来布局,并控制按钮的显示位置 tk.Button(root, text="登录", width=10, command=login).grid(row=3, column=0, columnspan=2,sticky="w", padx=10, pady=5) tk.Button(root, text="退出", width=10, command=root.quit).grid(row=3, column=1, columnspan=2,sticky="e", padx=10, pady=5) # 开启事件主循环 root.mainloop()
place()
与前两种布局方法相比,采用 place() 方法进行布局管理要更加精细化,通过 place() 布局管理器可以直接指定控件在窗体内的绝对位置,或者相对于其他控件定位的相对位置。
下面对 place 布局管理器的常用属性做相关介绍:
属性 | 说明 |
anchor | 定义控件在窗体内的方位,参数值N/NE/E/SE/S/SW/W/NW 或 CENTER,默认值是 NW |
bordermode | 定义控件的坐标是否要考虑边界的宽度,参数值为 OUTSIDE(排除边界) 或 INSIDE(包含边界),默认值 INSIDE。 |
x、y | 定义控件在根窗体中水平和垂直方向上的起始绝对位置 |
relx、rely | 1. 定义控件相对于根窗口(或其他控件)在水平和垂直方向上的相对位置(即位移比例),取值范围再 0.0~1.0 之间 2. 可设置 in_ 参数项,相对于某个其他控件的位置 |
height、width | 控件自身的高度和宽度(单位为像素) |
relheight、relwidth | 控件高度和宽度相对于根窗体高度和宽度的比例,取值也在 0.0~1.0 之间 |
通过上述描述我们知道,relx和rely参数指定的是控件相对于父组件的位置,而relwidth和relheight参数则是指定控件相对于父组件的尺寸大小。
注意:这里父组件指的是当前可操作控件的上层组件,比如在没有使用容器控件(frame)的窗体中,控件的父组件就是主窗口本身。
上述表格中关于距离位置的参数容易产生“疑惑”,下面通过一组简单的示例来进一步说明:
from tkinter import * #主窗口 win = Tk() win.title("艾派森") win.iconbitmap('favicon.ico') #创建一个frame窗体对象,用来包裹标签 frame = Frame(win, relief=SUNKEN, borderwidth=2, width=450, height=250) # 在水平、垂直方向上填充窗体 frame.pack(side=TOP, fill=BOTH, expand=1) # 创建 "位置1" Label1 = Label(frame, text="位置1",bg='blue',fg='white') # 使用 place,设置第一个标签位于距离窗体左上角的位置(40,40)和其大小(width,height) # 注意这里(x,y)位置坐标指的是标签左上角的位置(以NW左上角进行绝对定位,默认为NW) Label1.place(x=40,y=40, width=60, height=30) # 设置标签2 Label2 = Label(frame, text="位置2",bg='purple',fg='white') # 以右上角进行绝对值定位,anchor=NE,第二个标签的位置在距离窗体左上角的(180,80) Label2.place(x=180,y=80, anchor=NE, width=60, height=30) # 设置标签3 Label3 = Label (frame, text="位置3",bg='green',fg='white') # 设置水平起始位置相对于窗体水平距离的0.6倍,垂直的绝对距离为80,大小为60,30 Label3.place(relx=0.6,y=80, width=60, height=30) # 设置标签4 Label4 = Label (frame, text="位置4",bg='gray',fg='white') # 设置水平起始位置相对于窗体水平距离的0.01倍,垂直的绝对距离为80,并设置高度为窗体高度比例的0.5倍,宽度为80 Label4.place(relx=0.01,y=80,relheight=0.4,width=80) #开始事件循环 win. mainloop()
注意:在一个父组件中 place()方法可以与 grid() 方法混合使用,要与 pack() 进行区别。
布局管理控件
在前面讲解其他的 Tkinter 控件时,我们列举的大多数示例都是将控件直接放置在主窗口(即根窗口)内,这样做的目的是为了便于大家理解。但在实际的开发过程中,控件一般放置在容器中,比如 Frame 容器控件,如同 HTML 中的<div>标签一样,把容器看做成一个框架,其他控件则是这个框架中的“元素”。
这里介绍了三种常用的容器控件以及它们的使用方法,分别是 Frame、LabelFrame、PanedWindow
Frame控件
Frame 本质上也是一个矩形窗体,同其他控件一样也需要位于主窗口内。我们可以在主窗口内放置多个 Frame 控件,并且每个 Frame 中还可以嵌套一个或者多个Frame,从而将主窗口界面划分成多个区域。
Frame 控件的常用属性如下表所示:
属性 | 说明 |
bg | 设置 Frame 的背景颜色 |
bd | 指定 Frame 的边框宽度 |
colormap | 指定 Frame 组件及其子组件的颜色映射 |
container | 布尔值参数,若参数值为 True,则窗体将被用作容器使用,一些其他程序也可以被嵌入。 |
cursor | 指定鼠标在 Frame 上飘过的鼠标样式,默认由系统指定 |
height/width | 设置 Frame 的高度和宽度 |
highlightbackground | 指定当 Frame 没有获得焦点的时候高亮边框的颜色,通常由系统指定为标准颜色 |
highlightcolor | 指定当 Frame 获得焦点的时候高亮边框的颜色 |
highlightthickness | 指定高亮边框的宽度,默认值是 0 |
padx/pady | 距离主窗口在水平/垂直方向上的外边距 |
relief | 指定边框的样式,参数值 "sunken","raised","groove" 或 "ridge","flat",默认为 "falt' |
takefocus | 布尔值参数,默认为 False,指定该组件是否接受输入焦点(即用户通过 Tab 键将焦点转移上来) |
下面看一组简单的示例,通过 Frame 将主窗口分成左右两个部分,如下所示:
1.
import tkinter as tk win = tk.Tk() win.title("艾派森") win.geometry('400x350+200+200') win.iconbitmap('favicon.ico') # 在主窗口上添加一个frame控件 frame1 = tk.Frame(win) frame1.pack() # 在frame_1上添加另外两个frame, 一个在靠左,一个靠右 # 左侧的frame frame_left = tk.Frame(frame1) tk.Label(frame_left,text='左侧标签1',bg='green',width=10,height=5).grid(row =0,column=0) tk.Label(frame_left,text='左侧标签2',bg='blue',width=10,height=5).grid(row = 1 ,column =1) frame_left.pack(side=tk.LEFT) frame_right = tk.Frame(frame1) tk.Label(frame_right,text='右侧标签1',bg='gray',width=10,height=5).grid(row = 0 ,column =1) tk.Label(frame_right,text='右侧标签2',bg='pink',width=10,height=5).grid(row = 1 ,column =0) tk.Label(frame_right,text='右侧标签3',bg='purple',width=10,height=5).grid(row= 1,column=1) frame_right.pack(side=tk.RIGHT) win.mainloop()
上述示例利用 Frame 控件将主窗口分成了左右两个子区域,同时在各自区域中添加了 Label 标签,而且区域之间互不干扰。采用这种分区、分块的布局方式,可以使得 GUI 程序更加规范、简洁化。
LabelFrame控件
LabelFrame 控件也是一种容器类型的控件,它属于是 Frame 控件的变体,因此它们的属性选项大体相同。
在默认情况下,LabelFrame 会在其包裹的子组件周围绘制一个边框和一个标题。当我们想要将一些相关的组件分为一组时,就可以使用 LabelFrame 组件,比如把一系列 Radiobutton(单选按钮)放在一起来供用户选择。
同 Frame 控件一样,LabelFrame 的主要作用也是对控件进行分组处理,下面看一个具体的实例:
PanedWindow控件
PanedWindow(窗格界面)也可以理解成一个特殊的 Frame 控件,它是 Tkinter 8.4 版本后新增的空间管理组件,其主要目的是为其他组件提供一个容器或者框架,从而实现以分块的形式对图形界面进行布局。
与 Frame 控件不同, PanedWindow 允许用户自主地调整界面划分以及每块区域的大小。因此,当您需要让用户自己调节每块区域的大小时,就可以采用 PanedWindow 作为组件载体来进行界面的布局。
不仅如此 PanedWindow 组件还提供了“手柄” 功能(设置参数 showhandle=True 来启用),通过拖动“手柄”图标也可以改变每块区域的大小。
其中 master 表示父组件,即包裹该组件的上层组件。其常用属性如下表所示:
属性 | 说明 |
handlepad | 1. 调节“手柄”的位置 2. 比如当 orient ='vertical' 设置垂直时,handlepad 表示“分割线”上的手柄与左端的距离,默认为 8 像素 |
handlesize | 设置“手柄”的尺寸(由于“手柄”必须是一个正方形,所以是设置正方形的边长)默认为 8 像素 |
opaqueresize | 1. 该选项定义了用户调整窗格尺寸的操作,如果该选项的值为 True(默认),窗格的尺寸随用户鼠标的拖拽而改变 2. 如果该选项的值为 False,那么窗格的尺寸,在用户释放鼠标时才会更新到新的位置上 |
orient | 指定窗格的分布方式,默认为水平方向分布("horizontal"),或者还可以设置为垂直纵向分布("vertical") |
relif | 指定边框的样式,默认为 "flat",还可以设置为 "sunken","raised","groove" 或 "ridge" |
sashpad | 设置每一条分割线到窗格间的间距 |
sashrelief | 设置分割线的样式,默认值是:"flat",还可以设置 "sunken","raised","groove" 或 "ridge" |
sashwidth | 设置分割线的宽度 |
showhandle | 设置是否显示调节窗格的手柄,默认为 False |
height/width | 设置 PanedWindow 的高度、宽度,若不设置,则其大小由其子组件的尺寸决定 |
PanedWindow 的常用方法如下表所示:
方法 | 说明 |
add(child) | 添加一个新的子组件到窗格中语法格式 add(child,**option),参数值 after、before、sticky |
forget(child) | 删除一个子组件 |
panecget(child, option) | 获得子组件指定选项的值 |
paneconfig(child, **options) | 设置子组件的各种选项 |
panes() | 将父组件中包含的子组件以列表的形式返回 |
sash_coord(index) | 返回一个二元组表示指定分割线的起点坐标 |
sash_place(index, x, y) | 将指定的分割线移动到一个新的位置 |
下面示例设计一个简单的界面布局,然后将图形界面分割成四部分:创建一个水平方向的 PanedWindow,并向其中添加两个 Label 组件,之后创建一个垂直的方向的 PanedWindow,并向其中中添加两个 Label 标签。示例代码如下:
import tkinter as tk win = tk.Tk() win.title("艾派森") win.geometry('400x400+200+200') win.iconbitmap('favicon.ico') # 创建一个水平方向的 panedwindow,并添加到主窗口中,默认为水平方向 p_window1 = tk.PanedWindow(win) p_window1.pack(fill=tk.BOTH, expand=1) # 在窗口区的左侧添加两个水平方向的 Label left1 =tk. Label(p_window1, text='百度', bg='#7CCD7C', width=10,font=('微软雅黑',15)) p_window1.add(left1) left2 =tk.Label(p_window1, text='网址:www.baidu.com', bg='#9AC0CD', width=10,font=('微软雅黑',15)) p_window1.add(left2) # 创建一个垂直方向的panedwindow,并添加一个手柄,设置分割线样式 p_window2 = tk.PanedWindow(orient=tk.VERTICAL,showhandle=True,sashrelief='sunken') # 添加到 p_window1中 p_window1.add(p_window2) # 在 p_window2 中添加两个垂直方向的标签 top_label =tk. Label(p_window2, text='教程', bg='#7171C6', height=8,font=('宋体',15)) p_window2.add(top_label) bottom_label =tk. Label(p_window2, text='辅导班', bg='#8968CD',font=('宋体',15)) p_window2.add(bottom_label) win.mainloop()
注意:从上述示例中可以看出 PanedWindw 会为每一个 Label 控件创建一个独立的窗格, 当我们将鼠标悬停在两个控件接壤处的白色边框上时,就会出现可以上下或者左右拉伸的指示光标,用户按照可以按照自己的意愿来调整每块区域的大小。
对话框控件
在前面,我们花费了大量的时间讲解了 Tkinter 中常用基本控件,通过对这些控件的学习,我们对 GUI 开发有了基本的认识与掌握,一个完整的 GUI 程序就是由这些组件以合理、美观的布局方式构成的。
除了基本的控件之外,Tkinter 还提供了三种对话框控件:
- 文件选择对话框:filedailog
- 颜色选择对话框:colorchooser
- 消息对话框:messagebox
这些对话框的使用能够在一定程度上增强用户的交互体验,下面对这些对话框控件进行详细地介绍。
文件选择对话框
文件对话框在 GUI 程序中经常的使用到,比如上传文档需要从本地选择一个文件,包括文件的打开和保存功能都需要一个文件对话框来实现。Tkinter 提供文件对话框被封装在tkinter.filedailog
模块中,该模块提供了有关文件对话框的常用函数,经常使用的有以下几个:
方法 | 说明 |
Open() | 打开个某个文件 |
SaveAs() | 打开一个保存文件的对话框 |
askopenfilename() | 打开某个文件,并以包函文件名的路径作为返回值 |
askopenfilenames() | 同时打开多个文件,并以元组形式返回多个文件名 |
askopenfile() | 打开文件,并返回文件流对象 |
askopenfiles() | 打开多个文件,并以列表形式返回多个文件流对象 |
asksaveasfilename() | 选择以什么文件名保存文件,并返回文件名 |
asksaveasfile() | 选择以什么类型保存文件,并返回文件流对象 |
askdirectory | 选择目录,并返回目录名 |
上述方法的常用参数值如下所示:
参数 | 说明 |
defaultextension | 指定文件的后缀名,当保存文件时自动添加文件名,如果自动添加了文件的后缀名,则该选项值不会生效 |
filetypes | 指定筛选文件类型的下拉菜单选项,该选项值是由 2 元祖构成的列表,其中每个二元祖由两部分组成 (类型名,后缀),比如 filetypes = [("PNG","*.png"), ("JPG", "*.jpg"), ("GIF","*.gif"),("文本文件","*.txt")...] ———————————————— 版权声明:本文为CSDN博主「艾派森」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_64336780/article/details/127704912 |
initialdir | 指定打开/保存文件的默认路径,默认路径是当前文件夹 |
parent | 如果不指定该选项,那么对话框默认显示在根窗口上,通过设置该参数可以使得对话框显示在子窗口上 |
title | 指定文件对话框的标题 |
下面看一组具体的实例应用:
from tkinter import * import tkinter.filedialog # 注意次数要将文件对话框导入 # 定义一个处理文件的相关函数 def askfile(): # 从本地选择一个文件,并返回文件的目录 filename = tkinter.filedialog.askopenfilename() if filename != '': lb.config(text= filename) else: lb.config(text='您没有选择任何文件') root = Tk() root.config(bg='#87CEEB') root.title("艾派森") root.geometry('400x200+300+300') root.iconbitmap('favicon.ico') btn=Button(root,text='选择文件',relief=RAISED,command=askfile) btn.grid(row=0,column=0) lb = Label(root,text='',bg='#87CEEB') lb.grid(row=0,column=1,padx=5) # 显示窗口 root.mainloop()
下面再看一组“保存文件”的示例代码如下:
import tkinter as tk from tkinter import filedialog from PIL import Image def open_img(): try: global img filepath = filedialog.askopenfilename() # 打开文件,返回该文件的完整路径 filename.set(filepath) img = Image.open(filename.get()) except Exception as e: print("您没有选择任何文件",e) def save_png(): try: filetypes = [("PNG","*.png"), ("JPG", "*.jpg"), ("GIF","*.gif"),("txt files","*.txt"),('All files','*')] # 返回一个 pathname 文件路径字符串,如果取消或者关闭则返回空字符,返回文件如何操作是后续代码的事情, # 该函数知识返回选择文件的文件名字,不具备保存文件的能力 filenewpath= filedialog.asksaveasfilename(title='保存文件', filetypes=filetypes, defaultextension='.png', initialdir='C:/Users/Administrator/Desktop' ) path_var.set(filenewpath) # 保存文件 img.save(str(path_var.get())) except Exception as e: print(e) window = tk.Tk() window.title("艾派森") window.geometry('400x200+300+300') window.iconbitmap('favicon.ico') filename = tk.StringVar() path_var = tk.StringVar() # 定义读取文件的组件 entry = tk.Entry(window, textvariable=filename) entry.grid(row=1, column=0, padx=5, pady=5) tk.Button(window, text='选择文件', command=open_img).grid(row=1, column=1, padx=5, pady=5) # 定义保存文件的组件 entry1 = tk.Entry(window, textvariable=path_var) entry1.grid(row=2, column=0, padx=5, pady=5) tk.Button(window, text='保存文件', command=save_png).grid(row=2, column=1, padx=5, pady=5) window.mainloop()
颜色选择对话框
颜色选择对话框(colorchooser),提供了一个非常友善的颜色面板,它允许用户选择自己所需要的颜色。 当用户在面板上选择一个颜色并按下“确定”按钮后,它会返回一个二元祖,其第 1 个元素是选择的 RGB 颜色值,第 2 个元素是对应的 16 进制颜色值。颜色选择对话款主要应用在画笔、涂鸦等功能上,通过它可以绘制出五彩缤纷的颜色,该对话框的使用非常简单,主要有以下两个常用方法:
方法 | 说明 |
askcolor() | 打开一个颜色对话框,并将用户选择的颜色值以元组的形式返回(没选择返回None),格式为((R, G, B), "#rrggbb") |
Chooser() |
打开一个颜色对话框,并用户选择颜色确定后,返回一个二元组,格式为((R, G, B), "#rrggbb") |
常用的颜色对话框的参数值如下表所示:
属性 | 说明 |
default | 要显示的初始的颜色,默认颜色是浅灰色(light gray) |
title | 指定颜色选择器标题栏的文本,默认标题为“颜色” |
parent | 1. 如果不指定该选项,那么对话框默认显示在根窗口上 2. 如果想要将对话框显示在子窗口上,那么可以设置 parent = 子窗口对象 |
下面看一组简单的使用示例:
import tkinter as tk from tkinter import colorchooser root = tk.Tk() root.title("颜色选择") root.geometry('400x200+300+300') root.iconbitmap('favicon.ico') def callback(): # 打开颜色对话款 colorvalue = tk.colorchooser.askcolor() # 在颜色面板点击确定后,会在窗口显示二元组颜色值 lb.config(text='颜色值:'+ str(colorvalue)) lb=tk.Label(root,text='',font=('宋体',10)) # 将label标签放置在主窗口 lb.pack() tk.Button(root, text="点击选择颜色", command=callback, width=10, bg='#9AC0CD').pack() # 显示界面 root.mainloop()
消息对话框
关于消息对话款(messagebox),在前面介绍其他控件时已经使用过,在这里仅对它做简单介绍。消息对话框主要起到信息提示、警告、说明、询问等作用,通常配合“事件函数”一起使用,比如执行某个操作出现了错误,然后弹出错误消息提示框。通过使用消息对话框可以提升用户的交互体验,也使得 GUI 程序更加人性化。消息对话框主要包含了以下常用方法:
方法 | 说明 |
askokcancel(title=None, message=None) | 打开一个“确定/取消”的对话框 |
askquestion(title=None, message=None) | 打开一个“是/否”的对话框。 |
askretrycancel(title=None, message=None) | 打开一个“重试/取消”的对话框 |
askyesno(title=None, message=None) | 打开一个“是/否”的对话框 |
showerror(title=None, message=None) | 打开一个错误提示对话框 |
showinfo(title=None, message=None) | 打开一个信息提示对话框 |
showwarning(title=None, message=None) | 打开一个警告提示对话框 |
上述方法拥有相同的选项参数,如下表所示:
属性 | 说明 |
default | 1. 设置默认的按钮(也就是按下回车响应的那个按钮) 2. 默认是第一个按钮(像“确定”,“是”或“重试”) 3. 可以设置的值根据对话框函数的不同,可以选择 CANCEL,IGNORE,OK,NO,RETRY 或 YES |
icon | 1. 指定对话框显示的图标 2. 可以指定的值有:ERROR,INFO,QUESTION 或 WARNING 3. 注意:不能指定自己的图标 |
parent | 1. 如果不指定该选项,那么对话框默认显示在根窗口上 2. 如果想要将对话框显示在子窗口上,那么可以设置 parent= 子窗口对象 |
上述方法的返回值一般会是一个布尔值,或者是“YES”,“NO”,“OK”等,这些方法使用较为简单,此处不进行逐一列举。