上一篇:Python tkinter(GUI编程)模块全解(上)_Python zzy的博客-CSDN博客
Checkbutton即多选框,用户可以勾选或取消勾选。Checkbutton可以绑定一个variable,一般是BooleanVar。Checkbutton拥有Button的参数之外,还可以有一些别的参数。
参考资料:Python ---(三)Tkinter窗口组件:Checkbutton_近视的脚踏实地的博客-CSDN博客
Checkbutton(master=None, **kw)
参数 | 作用 |
variable | 与Checkbutton选择相关的Variable |
onvalue | 多选框选中时variable的值,默认为1 |
offvalue | 多选框未选中时variable的值,默认为0 |
selectcolor | 选择方框的颜色 |
selectimage | 选中时的图片(须指定image参数) |
indicatoron | 是否显示为勾选框样式,默认为True |
常用方法:
方法 | 作用 |
select() | 选中多选框 |
deselect() | 取消选中选框 |
toogle() | 切换选框的选中状态(反选选框) |
invoke() | 调用Checkbutton的command(disabled无效) |
flash() | 使Checkbutton闪烁几次(在normal和active几次切换) |
from tkinter import *
root = Tk()
root.geometry("200x200")
def tg():
print("选中/取消选中")
cb = Checkbutton(root, text="toogle", command=tg)
cb.pack()
mainloop()
可以尝试点击Checkbutton,左边的方框就会打上勾或取消打勾。每次选择后都会打印"选中/取消选中"。
from tkinter import *
root = Tk()
root.geometry("200x200")
def tg():
print("当前状态为:", cb_var.get())
cb_var = BooleanVar()
cb = Checkbutton(root, text="toogle", command=tg, variable=cb_var)
cb.pack()
mainloop()
把多选按钮绑定到一个Var上,这样就可以获取Checkbutton的值。
Checkbutton有两种样式,一种是上面的勾选框样式,还可以设置为一个按钮盒的样式。默认是显示为勾选框的样式,如果把indicatoron设置为False也可以设置为按钮的样式。
from tkinter import *
root = Tk()
root.geometry("200x200")
cb = Checkbutton(root, text="toogle", indicatoron=False)
cb.pack()
mainloop()
与多选框相对应,Radiobutton是单选框。多个单选框可以绑定一个variable,这个variable的值是选中的单选框的值。
参考资料:Python ---(四)Tkinter窗口组件:Radiobutton_近视的脚踏实地的博客-CSDN博客
Radiobutton(master=None, cnf={}, **kw)
Radiobutton的参数和Checkbutton几乎完全一样,不同的是Radiobutton没有onvalue和offvalue这两个参数,而是由value这个参数代替。value参数的作用是:指定单选框选中时绑定的Var的值。
常用方法和Checkbutton介绍的几个基本一样,但是没有toogle方法。
一般情况下Radiobutton会出现多个,而Checkbutton只出现一个。
from tkinter import *
root = Tk()
root.geometry("200x200")
var = StringVar()
var.set("A")
Radiobutton(root, text="A. Python", variable=var, value="A").pack()
Radiobutton(root, text="B. C", variable=var, value="B").pack()
Radiobutton(root, text="C. Java", variable=var, value="C").pack()
mainloop()
上面的三个单选框,都绑定了一个variable,还指定了一个value参数。当variable的值被设为单选框的value,那么这个选框将是选中的状态。当点击单选按钮,variable的值就被设为这个单选按钮的值。因为variable的值只能有一个,所以你只能在绑定该variable的单选按钮里面选中一个单选按钮。
Menu也就是菜单,菜单一般有两种,一种是窗口上的菜单,一种是弹出式菜单。
参考资料:Python ---(十三)Tkinter窗口组件:Menu_近视的脚踏实地的博客-CSDN博客
Menu(master=None, cnf={}, **kw)
参数 | 作用 |
tearoff | 是否允许用户分离菜单,默认为True |
title | 分离菜单的标题 |
tearoffcommand | 用户分离菜单时执行的事件 |
postcommand | 菜单被打开时执行的事件 |
常用方法:
方法 | 作用 |
add(itemType, **kw) | 添加一个菜单项,itemType是command, cascade, checkbutton, radiobutton, separator之一 |
insert(index, itemType, **kw) | 在index位置插入菜单项 |
add_command(**kw) | 添加命令菜单项 |
add_cascade(**kw) | 添加分层菜单项 |
add_checkbutton(**kw) | 添加多选框菜单项 |
add_radiobutton(**kw) | 添加单选框菜单项 |
add_separator(**kw) | 添加菜单分割线 |
delete(index1, index2=None) | 删除位于index1(到index2之间)的菜单项 |
entrycget(index, option) | 获取位于index菜单项的option值 |
entryconfig(index, **kw) | 更改位于index菜单项的参数的值 |
post(x, y) | 在(x, y)位置弹出菜单 |
unpost() | 取消弹出菜单 |
invoke(index) | 执行位于index菜单项的command,如果菜单项是单选框或多选框,则选中它们。 |
type(index) | 返回位于index菜单项的类型,是command, cascade, checkbutton, radiobutton, separator之一 |
from tkinter import *
root = Tk()
menubar = Menu(root)
root.config(menu=menubar) #把菜单绑定root
mainloop()
这样,我们就成功创建出一个菜单,并且绑定了显示的窗口。不过这样的菜单什么都没有,接下来我们要在菜单中添加菜单项。
add方法可以添加菜单项。第一个参数itemType指定菜单项的类型,马上会介绍到。add(itemType)也可以被add_itemType()所替换。你还可以提供如下参数**kw(activebackground, activeforeground, bg, fg由于之前的组件介绍过,这里不介绍了):
参数 | 作用 |
accelerator | 显示菜单的补充说明标签 |
label | 菜单项显示的标签 |
font | 标签的字体 |
bitmap | 菜单项显示的位图 |
image | 菜单项显示的图片 |
compound | 图片显示于标签的方位 |
state | 菜单项的状态 |
underline | 在标签的第几个索引的字符处画下划线,用来绑定Alt快捷键 |
columnbreak | 从此菜单项开始另起一列显示 |
hidemargin | 菜单项长度适应label长度,默认为True |
command | 点击菜单项时执行的回调函数 |
menu | 绑定的分层子菜单(add_cascade) |
selectcolor | 单选或多选按钮菜单的selectcolor |
selectimage | 单选或多选按钮菜单的selectimage |
value | 单选按钮菜单的value |
variable | 单选或多选按钮菜单绑定的variable |
onvalue | 多选按钮菜单的onvalue |
offvalue | 多选按钮菜单的offvalue |
menu.add_command(**kw)相当于menu.add("command", **kw)
add_command方法在菜单中添加一个命令菜单项。它有如下参数:
下面, 让我们给菜单创建一个命令,点击时打印一段文字。
from tkinter import *
root = Tk()
menubar = Menu(root)
root.config(menu=menubar)
menubar.add_command(label="Click", command=lambda:print("Hello"))
mainloop()
点击菜单的Click按钮,就会执行print("Hello")
菜单可以有层级之分。最上层的菜单就是绑定了root的菜单,下面可以有一些子菜单,继承绑定窗口的父菜单,实现分层效果。
from tkinter import *
root = Tk()
menubar = Menu(root)
root.config(menu=menubar)
filemenu = Menu(menubar)
filemenu.add_command(label="Save", command=lambda:print("OK!"))
menubar.add_cascade(label="File", menu=filemenu)
mainloop()
首先需要创建一个菜单,继承绑定窗口的菜单menubar,然后添加这个子菜单的项目。接着,需要把这个子菜单添加到父菜单中,需要提供一个menu参数指定添加的子菜单。
子菜单也可以有子菜单。如下示例:
from tkinter import *
root = Tk()
menubar = Menu(root)
root.config(menu=menubar)
filemenu = Menu(menubar)
savemenu = Menu(filemenu)
menubar.add_cascade(label="File", menu=filemenu)
filemenu.add_cascade(label="Save", menu=savemenu)
savemenu.add_command(label="save1")
savemenu.add_command(label="save2")
mainloop()
当我们点击菜单上的虚线,可以跳出一个工具窗口,这就是分离菜单。
分离菜单功能有很多问题,并且大多数应用都没有这个功能,建议大家把它禁用。如果想要禁用分离菜单功能,可以在定义Menu的时候把tearoff参数设置为False。
Menu(menubar, tearoff=False)
accelerator可以对菜单项进行补充。一般这个参数指定的是一个加速键(快捷键)名称,比如Ctrl+N这种。
不过,即使指定了accelerator参数也没有真正的绑定快捷键,需要使用bind来进行绑定。
from tkinter import *
root = Tk()
menu = Menu(root)
root.config(menu=menu)
def new(event=None):
print("New file")
fm = Menu(menu)
menu.add_cascade(label="File", menu=fm)
fm.add_command(label="New", accelerator="Ctrl+N", command=new)
root.bind("", new)
mainloop()
按下Ctrl-N或点击菜单,执行new函数。
underline参数指定一个索引,绑定一个Alt快捷键。指定了underline的菜单项可以快捷触发。触发方式是:先按下Alt,然后下划线会显示出来,再按下菜单项标签下划线上的字符即可执行这个菜单项。
from tkinter import *
root = Tk()
menu = Menu(root)
root.config(menu=menu)
def new():
print("New file")
menu.add_command(label="New", underline=0, command=new)
mainloop()
add_separator方法可以给菜单添加一条分割线。
from tkinter import *
root = Tk()
menu = Menu(root)
root.config(menu=menu)
fm = Menu(menu, tearoff=False)
menu.add_cascade(label="File", menu=fm)
fm.add_command(label="New File")
fm.add_command(label="Save")
fm.add_separator() #添加分割线
fm.add_command(label="Exit")
mainloop()
分割线常用于分隔不同类的菜单项,比如编辑器中,打开文件、保存文件、退出几个文件操作类别都用分隔线隔开。
如果要弹出菜单,那么不需要绑定到窗口(root.config(menu=menu)),当然绑定也没关系。弹出窗口需要使用post方法,需要提供x, y两个参数。但这两个参数必须是屏幕上的位置,x_root和y_root。
下面的示例:当右击鼠标时在鼠标处弹出菜单。
from tkinter import *
root = Tk()
menu = Menu(root)
def show(event):
menu.post(event.x_root, event.y_root)
def cp():
print("Copy")
menu.add_command(label="Copy", underline=0, command=cp)
root.bind("", show)
mainloop()
Menubutton是一个Button的样式,可以绑定一个菜单,点击后弹出菜单。这个组件比较老,现在可以用Menu实现Menubutton的功能了,不过Menubutton在某些情况下要更简单好用一些。
参考资料:Python ---(十四)Tkinter窗口组件:Menubutton_近视的脚踏实地的博客-CSDN博客
Menubutton(master=None, cnf={}, **kw)
参数和Button基本一样,但是没有command,还有一些其他的参数。
参数 | 作用 |
menu | 绑定一个菜单 |
direction | 位于按钮的菜单弹出方位,有"left"(左),"right"(右),"above"(上),"below"(下),默认是below |
from tkinter import *
root = Tk()
mb = Menubutton(root, text="弹出")
mb.pack()
menu = Menu(mb)
def cp():
print("Copy")
menu.add_command(label="Copy", command=cp)
mb.config(menu=menu)
mainloop()
需要注意的是,继承关系不要弄错。绑定到Menubutton的菜单的master必须是该Menubutton,否则菜单跳不出来。
现在,你已经学习了一部分组件。在学习更多组件之前,先要详细介绍一下组件的基类。在tkinter(Python)中,大多数组件都有共用的方法,这是因为它们都继承共同的类。如果你想自己了解一下继承关系,可以看Lib/tkinter/__init__.py。
在这些类中,有一些方法的参数默认为None,这意味着如果为None可以返回当前参数设定的值。
这个类是模块中最基本的类,所有组件甚至是Tk都继承这个类。不过,组件并不直接继承这个类,而是继承Widget类(Widget类直接继承BaseWidget类,而BaseWidget类直接继承Misc),比较特殊的Toplevel继承的是BaseWidget类。
after(ms, func=None, *args)
等待ms毫秒(1s=1000ms)后执行func,并将所需参数通过args传递给func函数。常用于循环执行函数。
from tkinter import *
root = Tk()
def call(timer):
timer -= 1
print(timer)
root.after(1000, call, timer)
call(5)
mainloop()
如上示例,首先调用了一次call方法,在call方法里面将timer减去1,然后等待1秒后,将timer减去1后的值传递给call函数,然后在call函数里面再减一。每隔一秒就会打印一个数字。
after_cancel(id)
after方法返回一个标识符,可以传递给after_cancel方法取消after执行。
from tkinter import *
root = Tk()
def call(timer):
timer -= 1
print(timer)
id = root.after(1000, call, timer)
if timer <= 0:
root.after_cancel(id)
call(5)
mainloop()
如果检测到timer <= 0,after将会被取消,call函数也不会再执行。只有在after处于等待状态时,after_cancel才有效。
bell()
响铃一次,可参考Python tkinter一些十分灵活的运用方式和实用函数的第四节。
bind(sequence=None, func=None, add=None)
绑定事件。详见上一篇。
bind_all(sequence=None, func=None, add=None)
窗口所有组件绑定事件。详见上一篇。
bindtags(tagList=None)
设置事件执行的顺序。详见上一篇。
cget(key)
返回组件的key参数的值。如:label.cget("text")获取label的text参数值。
clipboard_append(string)
将string添加复制到剪贴板,复制的内容会被添加到上一次复制的内容后面。如果想要复制string,需先执行clipboard_clear()。
clipboard_clear()
清空剪贴板。
clipboard_get()
获取复制的内容。
config = configure(cnf=None, **kw)
更改组件的参数。cnf上一篇介绍过,和**kw一样可以用来传递参数,不过传递给cnf的是一个字典。
destroy()
销毁组件。窗口类也有这个方法,但是继承于Wm。
event_generate(sequence, **kw)
生成虚拟事件。详见上一篇。
focus = focus_set()
使窗口的输入焦点指向该组件。如果窗口未激活,这个组件将在用户激活窗口后作为该窗口的输入焦点。
focus_force()
使组件直接获取焦点,窗口将自动激活。和focus_set不同的是,focus_set不会自动激活窗口。
focus_get()
返回获取焦点的子组件。如果窗口未被激活,那么将返回None。
focus_lastfor()
返回窗口激活后将获取焦点的子组件。和focus_get不同的是,focus_lastfor即使没有激活窗口,也会返回将在激活后获取焦点的子组件。
grab_release()
释放组件焦点抓取。
grab_set()
设置组件焦点抓取。使焦点永远保持在这个组件上,在释放抓取之前不能转移焦点,只能在这个组件上操作。如果应用在窗口上,那么只能在这个应用程序的这个窗口上进行操作,无法操作其他的窗口(只能拖拽移动)。
image_names()
获取组件内可以应用的所有的图像名称,是Tcl内部的名称字符串。
keys()
返回组件所有的可设置参数列表。
lift = tkraise(aboveThis=None)
将窗口堆叠顺序抬升。如果不指定aboveThis,则窗口置于此应用程序所有窗口的最上方。如果指定aboveThis,则窗口置于aboveThis窗口的上方。
lower(belowThis=None)
将窗口堆叠顺序下降。如果不指定belowThis,则窗口置于此应用程序所有窗口的最下方。如果指定belowThis,则窗口置于belowThis窗口的下方。
nametowidget(name)
返回名为name的子组件。比如定义了一个Button(root, name="MyButton"),可以通过root.nametowidget("MyButton")返回Button对象本身。如果不会产生混淆,可以只提供组件本身的名字,不用提供组件的完整名称。
selection_clear()
清除子组件的选中内容。
selection_get(**kw)
获取子组件中的选中内容,如没有则会报错。如果某个输入类组件设定了exportselection=False,那么在这个组件上的选中内容不会被检测到。
unbind(sequence)
解除绑定。详见上一篇。
unbind_all(sequence)
解除bind_all的绑定。
update()
在事件循环中刷新,并刷新用户的动作引起的事件。
update_idletasks()
在事件循环中刷新,但不会处理用户动作引起的事件。
quit()
该组件退出事件循环(mainloop),但不销毁本身。
wait_variable(name="PY_VAR")
一直阻塞直到variable改变。详见Python tkinter一些十分灵活的运用方式和实用函数第5节。
wait_visibility(window=None)
一直阻塞直到window可见性改变。详见Python tkinter一些十分灵活的运用方式和实用函数第5节。
wait_window(window=None)
一直阻塞直到window销毁。详见Python tkinter一些十分灵活的运用方式和实用函数第5节。
winfo_children()
返回该组件的子组件列表。
winfo_class()
返回该组件的类名。比如Entry组件的类名是"Entry"。
winfo_containing(rootX, rootY)
返回位于电脑屏幕rootX, rootY的子组件。
winfo_exists()
返回组件是否存在。如果组件存在返回1,不存在(被destroy)返回0.
winfo_geometry()
返回组件的geometry信息(需要先映射组件,否则不准),返回格式为widthxheight+x+y。注:不是设置!
winfo_height(), winfo_width()
分别返回组件的高和宽(需要先映射组件,否则不准),会随着窗口的改变而更新。
winfo_reqheight(), winfo_reqwidth()
分别返回组件定义时的高和宽(不需要映射组件),不会随着窗口的改变而更新。
winfo_id()
返回窗口绘制组件区域(也就是整个窗口中,除去标题和菜单栏部分)的标识符,是一个整数。可以用这个方法返回Windows Tk窗口内部绘制组件区域的句柄,(注意:不是整个tk窗口!参见winfo_frame)
winfo_frame()
返回窗口的标识符,是一个十六进制字符串。可以用这个方法返回Windows Tk窗口的句柄。
winfo_name()
返回组件的Tcl内部名称。也可以用str(widget)代替这一句。
winfo_parent()
返回组件的父组件。
winfo_pointerx(), winfo_pointery(), winfo_pointerxy()
分别返回鼠标在屏幕上的x位置,y位置,以及x,y位置的元组。
winfo_rootx(), winfo_rooty()
分别返回组件在屏幕上的x位置,y位置(需要先映射组件,否则不准)。
winfo_screenheight(), winfo_screenwidth()
分别返回屏幕的高和宽。
winfo_x(), winfo_y()
分别返回组件在父容器上的x位置,y位置(需要先映射组件,否则不准)。
winfo_rgb(color)
返回组件中名为color的颜色的RGB色彩值。返回的是一个三个值的元组,每个值介于0和65535之间。
winfo_server()
返回屏幕的服务器信息。如:Windows 10.0 18363 Win64
注:使用winfo系列方法返回组件尺寸信息的时候,必须要在组件映射或update之后才能有效调用。mainloop方法就是在循环update窗口以及里面的组件,所以在调用mainloop后不需要执行update,但在mainloop之前需要执行update。但是winfo_reqwidth(), winfo_reqheight()不需要。
参考资料:Toplevel顶级窗口和Tk根窗口方法汇总_近视的脚踏实地的博客-CSDN博客
WM是Window manager(窗口管理器)的缩写,所有窗口类继承Wm,也就是Tk和Toplevel。Wm类的方法以wm_作为开头,比如wm_destroy, wm_attributes,不过我们也可以写作destroy, attributes。在tk类中有很多这样的多名字的方法,这是因为类中对一些方法重命名过。
下面介绍Wm类(Tk和Toplevel)的方法。
注:由于方法过多,这里只筛选出可能有用的方法进行详细的解析。其他方法可见参考资料
aspect(minNumer=None, minDenom=None, maxNumer=None, maxDenom=None)
控制窗口的宽高比,使宽高比限制在:minNumer / minDenom ~ maxNumer / maxDenom。如果不设置参数,则返回这四个参数的元组。
attributes(*args)
设置窗口的各项属性。可以提供一个参数,是属性名称,将会返回窗口的属性值。如果再提供一个参数,则设置这个窗口的属性值。选项提供时,需要在前面加上一个-符号,比如:root.attributes("-alpha", 0.5)表示设置窗口半透明。
窗口的属性选项有:
选项 | 作用 | 系统 |
alpha | 设置窗口的不透明度,是一个0-1的浮点数,1.0表示不透明,0.0表示完全透明。 | Windows, Mac |
disabled | 窗口是否禁用,禁用时无法在窗口上进行任何操作 | Windows |
fullscreen | 窗口是否全屏,全屏和最大化不同,全屏时窗口最大的同时标题栏会隐藏。 | Windows, Mac |
modified | 窗口是否标记为改动过 | Mac |
titlepath | 设置窗口代理图标的路径 | Mac |
toolwindow | 窗口是否设置为工具窗口样式,可以参考Python tkinter一些十分灵活的运用方式和实用函数的第一节。 | Windows |
topmost | 窗口是否始终置顶显示 | Windows, Mac |
transparentcolor | 设置穿透颜色,可以参考Python tkinter一些十分灵活的运用方式和实用函数的第三节。 | Windows |
deiconify()
显示窗口(和withdraw方法相反)。
geometry(newGeometry=None)
设置窗口尺寸,newGeometry格式有以下几种:
iconbitmap(bitmap=None, default=None)
设置窗口图标为bitmap(是一个ico文件的路径字符串),如果设置default(一个文件名),那么该窗口的子窗口将自动设置图标为此图标文件。
iconify()
使窗口最小化。
iconphoto(default=False, *args)
设置窗口图标。如果default设置为True,那么该窗口的子窗口将自动设置图标为此图标文件。*args可以提供图标,提供的是PhotoImage对象。
maxsize(width=None, height=None)
设置窗口可以被拖拽的最大宽和高。
minsize(width=None, height=None)
设置窗口可以被拖拽的最小宽和高。
overrideredirect(boolean=None)
设置是否隐藏窗口的标题栏和边框。隐藏标题栏的窗口:
protocol(name=None, func=None)
当窗口检测到name协议的时候,执行func。协议是窗口管理器和应用的通信方式。最常用的协议是WM_DELETE_WINDOW,当用户点击窗口的关闭按钮时,将会调用func。此外还有一些协议:WM_SAVE_YOURSELF(当窗口被保存,被弃用),WM_TAKE_FOCUS(当窗口获取焦点,无效),但是都没有什么用。
下面的示例:在用户点击关闭按钮的时候,打印“你不能关闭”。
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
root.protocol("WM_DELETE_WINDOW", lambda:print("你不能关闭"))
mainloop()
默认窗口检测到WM_DELETE_WINDOW会执行窗口的destroy方法将窗口销毁,但是更改了WM_DELETE_WINDOW的方法后,就只会执行给定的func回调函数。
resizable(width=None, height=None)
设置是否允许改变窗口尺寸。
state(newstate=None)
设置窗口的状态,newstate可以是"normal"(正常), "iconic"(最小化), "withdrawn"(被隐藏), "icon"(Wm.iconwindow), "zoomed"(最大化)。
title(string=None)
设置窗口的标题。
transient(master=None)
设置窗口为master窗口的临时窗口,临时窗口没有最大化和最小化按钮,只有关闭按钮。 可以参考Python tkinter一些十分灵活的运用方式和实用函数的第一节。
withdraw()
隐藏窗口,和最小化不同的是,隐藏的窗口不会在任务栏上显示,用户无法还原。和deiconify方法相反。
Listbox是列表框,里面可以添加一些文本项目,在列表框中竖向显示。可以让用户选择它们。
参考资料:Python ---(七)Tkinter窗口组件:Listbox_近视的脚踏实地的博客-CSDN博客
Listbox(master=None, cnf={}, **kw)
参数 | 作用 |
width | 组件的宽,单位是字母的平均宽度 |
height | 组件的高,单位是项目的数量 |
listvariable | 设置与Listbox关联的variable,是一个StringVar,不同项目用空格隔开(不推荐)。 |
selectmode | 组件的选择模式,可以是"browse"(单选,可用鼠标拖动或方向键改变选择,默认模式), "single"(单选,只能鼠标点击改变选择), "extended"(多选,需拖动鼠标或结合Shift或Ctrl键才能多选), "multiple"(多选,点击多个选项就能多次选择) |
xscrollcommand | x方向滚动条(下一节介绍) |
yscrollcommand | y方向滚动条(下一节介绍) |
常用方法:
方法 | 作用 |
activate(index) | 将位于index位置的项目激活(在下方画下划线) |
bbox(index) | 返回位于index位置的项目的边框尺寸信息,返回值是(xoffset, yoffset, width, height),表示左上角的偏移和宽高。 |
curselection() | 返回被选中选项的索引的元组 |
delete(first, last=None) | 删除first到last的选项 |
insert(index, *elements) | 在列表框中添加单或多个选项 |
get(first, last=None) | 如果不指定last,返回first位置的选项;如果指定last,返回两个位置之间的选项 |
index(index) | 返回index位置的数字索引,如index("end")返回最后一个选项的数字索引 |
itemconfig(index, **option) | 设置index位置的选项的参数,可以设置的有:bg(background), fg(foreground), selectbackground, selectforeground |
itemcget(index, option) | 返回index位置的选项的option参数选项值 |
see(index) | 滚动列表框,使位于index位置的项目可见 |
selection_set(first, last=None) | 选中first到last的项目 |
selection_clear(first, last=None) | 取消选中first到last的项目 |
selection_includes(index) | 返回位于index位置的项目的选中状态,1表示选中,0表示未选中 |
selection_anchor(index) | 在index位置的项目设置锚点(类似于一个标记,可通过特殊索引"anchor"访问锚点) |
size() | 返回列表框中选项数量 |
from tkinter import *
root = Tk()
lb = Listbox(root)
lb.pack()
mainloop()
这样就创建了一个Listbox,不过里面什么项目也没有。
Listbox中有项目选中时会产生一个虚拟事件<
from tkinter import *
root = Tk()
lb = Listbox(root)
lb.pack()
for n in range(20):
lb.insert("end", n)
def select(event):
print(lb.curselection()) #打印选中项的索引
lb.bind("<>", select)
mainloop()
如图示,选中项目时会打印选中的项目索引。
see方法可以滚动列表框,使位于index位置的项目可见。
from tkinter import *
root = Tk()
lb = Listbox(root)
lb.pack()
for n in range(20):
lb.insert("end", n)
Button(root, text="see end", command=lambda:lb.see("end")).pack()
mainloop()
点击按钮后列表框滚动到了end位置。
下面是一个实例,用户可以添加或删除列表框中的内容。
from tkinter import *
root = Tk()
def add():
lb.insert("end", entry.get())
def remove():
try:
lb.delete(lb.curselection()[0])
except: #如果没有选中列表框内容会报错
pass
lb = Listbox(root)
lb.pack()
entry = Entry(root)
entry.pack()
Button(root, text="Add", command=add).pack()
Button(root, text="Remove", command=remove).pack()
root.mainloop()
Scrollbar也就是滚动条,可以起到滚动组件,使用户能够完整看到的效果。但也有部分组件不支持滚动条。
参考资料:Python ---(八)Tkinter窗口组件:Scrollbar_近视的脚踏实地的博客-CSDN博客
Scrollbar(master=None, cnf={}, **kw)
滚动条没有常规的参数height,只有width。
参数 | 作用 |
activerelief | 滚动条的滑块被激活时的relief样式 |
command | 滚动条被滚动更新时执行的回调函数,会传递给函数几个参数,可以直接传递给需滚动组件的xview和yview方法。 |
elementborderwidth | 滚动条和箭头的边框宽度 |
jump | 是否当鼠标松开长按滚动条才调用command,默认为False(此参数似乎无效)。 |
orient | 滚动条的方向,可以是"horizontal"(水平,横向), "vertical"(垂直,竖向),默认是vertical |
repeatdelay | 鼠标长按在滚动条上时,持续触发滚动条的准备时长,默认为300(ms) |
repeatinterval | 持续触发滚动条的间隔,默认为100(ms) |
常用方法:
方法 | 作用 |
get() | 返回滑块的位置,是一个元组,包含滑块左边或上边的位置,和滑块右边或下边的位置,都是0.0 ~ 1.0之间的浮点数,代表占整个滚动条的比例 |
set(*args) | 设置滑块的位置,需提供两个参数,分别是滑块左边或上边的位置,和滑块右边或下边的位置,都是0.0 ~ 1.0之间的浮点数,代表占整个滚动条的比例 |
from tkinter import *
root = Tk()
sb = Scrollbar(root)
sb.pack(side="right", fill="y")
mainloop()
这段代码在屏幕右侧绘制了一个滚动条。这个滚动条没有绑定任何可滚动的组件,所以没有任何用处。在映射滚动条时,通常会加入fill="y"这个参数,让滚动条完全伸展开,方便拖拽(在水平滚动条中是fill="x",grid布局则要指定sticky)。
在tkinter中有XView类和YView类,所有支持滚动条的组件继承它们。支持x方向滚动条则继承XView,支持y方向滚动条则继承YView。比如Listbox组件同时支持x,y方向滚动条,而Entry组件只支持x方向的滚动条。
下面介绍一下XView的方法(YView的方法和XView相比,只是方法名字中的xview改为了yview)。
方法 | 作用 |
xview(*args) | 在x方向滚动组件。需提供几个参数,第一个是滚动类型,可以是"moveto"(滚动到), "scroll"(向右或向下滚动)。如果滚动类型是moveto,则还需要提供一个参数表示滚动到的位置,是0.0 ~ 1.0之间的浮点数。如果滚动类型是scroll,则还需要提供滚动的数量,和滚动单位。滚动单位可以是"units"(按滚动单位滚动), "pages"(按页面滚动)。 |
xview_moveto(fraction) | 和xview(“moveto”, fraction) 一样 |
xview_scroll(number, what) | 和xview("scroll", number, what)一样 |
支持滚动条的组件,本身有xscrollcommand和yscrollcommand两个参数,可以设置为滚动条的set方法,滚动条拖拽的时候会让滚动条的位置改变。如果不设置这两个参数,那么滚动条位置拖拽后会返回原位。
同时还要设置滚动条的command参数为需滚动组件的xview或yview方法,因为command在滚动条拖拽时调用,会将滚动信息传递给command,使组件滚动。
orient参数指定滚动条的朝向。部分组件也有这个方法,都有两个可选值:"horizontal"(水平,横向), "vertical"(垂直,竖向)。
下面是这两个orient形态的滚动条:
horizontal | |
vertical |
Listbox继承XView和YView,支持滚动条,下面就以Listbox为例示范一下滚动条的绑定。
from tkinter import *
root = Tk()
sb = Scrollbar(root)
sb.pack(side="right", fill="y")
lb = Listbox(root, yscrollcommand=sb.set)
lb.pack(side="left", fill="both")
for i in range(100):
lb.insert("end", i)
sb.config(command=lb.yview)
mainloop()
运行效果:
Message是一个比较少用的组件,功能基本可以被Label替代。Message组件可以自动换行,指定Label组件的wraplength也可以达到这个功能,不过Message可能更加简便一些。
参考资料:Python ---(十六)Tkinter窗口组件:Message_近视的脚踏实地的博客-CSDN博客
Message(master=None, cnf={}, **kw)
参数和Label基本一样,但有一个参数aspect,表示组件达到多少像素换行。
Scale也就是标尺组件。用户可以通过拖拽滑块,设定一个数值。
参考资料:Tkinter 组件详解(十):Scale_来自江南的你的博客-CSDN博客
Scale(master=None, cnf={}, **kw)
参数 | 作用 |
length | 设置Scale的长度 |
width | 设置Scale的宽度 |
label | 在Scale上显示一个文字标签 |
command | Scale数值改变时执行的回调函数,会传递给该函数当前Scale的值 |
from_ | 设置Scale的最小值,默认是0 |
to | 设置Scale的最大值,默认是100 |
digits | 刻度数值最多显示的数字位数 |
orient | 设置Scale的朝向,可以是"horizontal"(水平)或"vertical"(垂直) |
resolution | 设置滑块拖动的步长(也就是拖动一次滑块,滑块移动的数值长度),默认为1 |
showvalue | 设置是否在滑块旁边显示当前的数值 |
sliderlength | 设置滑块的长度 |
sliderrelief | 设置滑块的样式,默认是"raised" |
tickinterval | 设置显示的刻度,默认不显示 |
troughcolor | 设置凹槽的颜色 |
variable | 设置与Scale值相关联的variable |
常用方法:
方法 | 作用 |
get() | 返回Scale的值 |
set(value) | 设置Scale的值 |
from tkinter import *
root = Tk()
scale = Scale(root)
scale.pack()
mainloop()
用户可以拖动滑块,设定滑块的值。
设置这两个参数可以设定拖拽的最小和最大值。
from tkinter import *
root = Tk()
scale = Scale(root, from_=10, to=30)
scale.pack()
mainloop()
滑块只能从10拖动到30。
tickinterval参数使Scale可以添加刻度数值。如from_=0, to=100, tickinterval=10的Scale:
垂直的Scale的刻度显示在左边,水平的Scale则显示在下面。
label参数可以显示在Scale旁边显示一个标签。例如:label="拖动滑块":
垂直的Scale的标签在右边,水平的Scale则在显示上面。
resolution参数设置Scale的步长,默认为1。如resolution=0.1, from_=0, to=100,那么你可以在0到100之间拖动滑块,每次可拖动0.1个数值。每次拖动的数值都是0.1,不能小于这个数。
下面是一个简单的小程序,用户可以拖拽Scale滑块控制背景的颜色。
from tkinter import *
root = Tk()
def change(x):
color = "#%02x%02x%02x"%(r.get(),
g.get(),
b.get()) #将普通的RGB色彩元组转换成16进制的形式
for w in root.winfo_children(): #设置Scale的背景色
w.config(bg=color)
r = Scale(root, from_=0, to=255, fg="red", command=change)
r.pack(side="left")
g = Scale(root, from_=0, to=255, fg="green", command=change)
g.pack(side="left")
b = Scale(root, from_=0, to=255, fg="blue", command=change)
b.pack(side="left")
mainloop()
Spinbox和Entry组件很类似,可以算是Entry组件的一个变形。Spinbox拥有Entry组件的所有参数。不同的是,Spinbox的侧面多了一个上箭头和一个下箭头,可以调节Spinbox的值。当然用户也可以在里面输入
参考资料:Python ---(十七)Tkinter窗口组件:Spinbox_近视的脚踏实地的博客-CSDN博客
Spinbox(master=None, cnf={}, **kw)
下面是Spinbox比Entry多的参数选项。
参数 | 作用 |
buttonbackground | Spinbox调节箭头的背景颜色 |
buttoncursor | 鼠标在调节箭头上方的样式 |
buttondownrelief | 下调节箭头的relief样式 |
buttonuprelief | 上调节箭头的relief样式 |
command | 点击调节箭头时执行的回调函数 |
from_ | 设置调节箭头调节的最小数值 |
to | 设置调节箭头调节的最大数值 |
format | 设置调节箭头调整数值的数值格式,使用%格式化,如:"%4.4f" |
increment | 调节箭头调节数值的步长 |
values | 设置调节箭头可调节值的元组,和from_, to只能指定一边 |
wrap | 可调节值是否可以循环调节,比如wrap=True, values=("0", "1", "2"),然后一直点击下箭头,那么Spinbox的值依次变成"0", "1", "2", "0", "1", "2"的循环。如果wrap=False,那么无法循环调节,调节到"2"点下箭头就无效了。默认wrap=False |
常用方法同Entry。
from tkinter import *
root = Tk()
spinbox = Spinbox(root)
spinbox.pack()
mainloop()
由于没有指定from_, to或values,所以箭头按了也无效。
如设置from_=0, to=10,那么点击上下箭头的时候,文本框里面的内容会在0到10之间调节。但用户仍然可以在Spinbox中输入任何内容。
increment参数指定点击箭头的步长,类似于Scale组件的resolution参数选项。
values参数和上面的from_, to, increment只能指定一边。values参数传递一个元组之类的序列。比如values=("Python", "C", "Java", "Tcl"),那么点击上下箭头的时候,文本框中的内容会在元组里面切换。
Spinbox可以设置为readonly状态,和Entry一样。设置为readonly的时候,文本框中不能输入,但是仍可以通过按上下箭头调节Spinbox的值。
OptionMenu是选项菜单,用户可以下拉一个选择菜单,指定OptionMenu的值。
参考资料:Python ---(十五)Tkinter窗口组件:OptionMenu_近视的脚踏实地的博客-CSDN博客
OptionMenu(master, variable, value, *values, **kwargs)
这个组件比较特殊,它继承Menubutton类,有一些必选参数。比如master参数在其他的组件是可选参数,如果不指定master将会自动继承主Tk窗口。而OptionMenu必选master, variable参数。
参数 | 作用 |
master | 指定父容器 |
variable | 指定绑定的variable,设为选项菜单的值 |
value | 选项菜单的初始选择值,没什么用,仍需要设置variable的值 |
*values | 选项菜单的可选项(不需要再加上value,初始选择值会自动添加到可选项中) |
**kwargs | OptionMenu继承Menubutton类,在此处指定Menubutton的**kw选项值 |
from tkinter import *
root = Tk()
var = StringVar()
var.set("Python") #设置OptionMenu的值
m = OptionMenu(root, var, "Python", "C", "Java")
m.pack()
mainloop()
此处创建了一个选项菜单,可以有3个可选项。获取OptionMenu的值,只需要执行绑定的variable的get方法。
PanedWindow组件是Tk8.4新增的组件,类似于Frame。不同的是,PanedWindow组件允许用户调节子组件的布局。每个添加到PanedWindow的子组件作为一个窗格管理。
参考资料:Python ---(十八)Tkinter窗口组件:PanedWindow_近视的脚踏实地的博客-CSDN博客
PanedWindow(master=None, cnf={}, **kw)
参数 | 作用 |
showhandle | 是否显示调整窗格布局的手柄,是一个正方形 |
orient | 窗格的分布朝向,可以是"horizontal"(水平), "vertical"(垂直) |
sashpad | 分割线和组件的间距 |
sashrelief | 分割线的relief样式,默认是"flat" |
sashwidth | 分割线的宽度 |
handlepad | 手柄在分割线上的位置,默认是8(像素) |
handlesize | 手柄的边长,默认是8(像素) |
opaqueresize | 窗格尺寸是否随鼠标拖拽而改变,默认为True,如果设为False,只有释放鼠标窗格尺寸才会改变 |
常用方法:
方法 | 作用 |
add(child, **options) | 将child组件添加到PanedWindow中,option选项稍后介绍 |
forget(child) | 从PanedWindow中移除child组件 |
panecget(child, option) | 返回child组件option选项的值 |
paneconfig(child, **options) | 设置child组件option选项的值 |
panes() | 返回子组件的列表 |
from tkinter import *
root = Tk()
w = PanedWindow(root, orient="horizontal")
w.pack(fill="both", expand=True)
mainloop()
这段代码创建了一个空的水平方向PanedWindow,需要在里面添加组件才能看出来。
add方法用于在PanedWindow中添加组件。如果是水平的PanedWindow,添加的组件都按水平方向排放。如果是垂直PanedWindow,添加的组件按竖直方向排放。
add(child, **options)
options可以是这些参数选项:
参数 | 作用 |
after | 将child组件排放到after组件的后面 |
before | 将child组件排放到before组件的前面 |
width | 排放时child的宽度 |
height | 排放时child的高度 |
minsize | 窗格长度的最小值(在水平PanedWindow中是窗格的宽,垂直则是窗格的高) |
padx | 组件的x方向间距 |
pady | 组件的y方向间距 |
sticky | 组件位于窗格的位置,和grid布局的sticky参数作用一样 |
from tkinter import *
root = Tk()
w = PanedWindow(root, orient="horizontal")
w.pack(fill="both", expand=True)
b = Button(w, text="1b")
w.add(b)
b = Button(w, text="2b")
w.add(b)
mainloop()
代码生成了两个按钮,中间有一个细小的间隔,是窗格之间的分割线。因为分割线默认是"flat",所以是看不见的, 如可见需设置sashrelief参数。可以拖拽这个分割线,来调整窗格之间的大小。
showhandle参数如果设置为True,将会在分割线的位置添加一个手柄。用户可以拖拽这个手柄,这样可以方便地调整窗格的大小。
手柄是一个正方形。
Text是多行文本输入框,和Entry不同的是,Entry只有单行。并且Text里面不仅能够插入文本,还可以插入图片、组件等,还可以有标记功能,对于特殊的内容改变颜色。
参考资料:Python ---(十)Tkinter窗口组件:Text_近视的脚踏实地的博客-CSDN博客
Text(master=None, cnf={}, **kw)
Text的参数有一大部分和Entry的参数相同,如光标、激活、颜色一类的参数。
参数 | 作用 |
width | Text的宽,以字符数量为单位 |
height | Text的高,以行数为单位 |
undo | 设置是否开启撤销功能,默认为False;开启撤销功能时,用户可以按下Ctrl+Z进行撤销操作 |
autoseparators | 设置是否自动插入撤销分隔,默认为True |
maxundo | 允许撤销的数量,设置为-1代表无限次 |
padx | 设置内容与边框的x方向间距 |
pady | 设置内容与边框的y方向间距 |
wrap | 设置Text的换行方式,可以是"none"(不自动换行), "char"(按字符换行), "word"(按单词换行) |
xscrollcommand | x方向滚动 |
yscrollcommand | y方向滚动 |
常用方法:
方法 | 作用 |
bbox(index) | 返回位于index字符的边界框位置(x, y, width, height),需先调用update方法 |
delete(start, end=None) | 删除从start到end的内容 |
insert(index, text, *tag) | 在index位置插入text,并标记为*tag |
dump(index1, index2=None, command=None, **kw) | 以列表形式返回Text的插入内容 |
get(index1, index2=None) | 返回index到index2的文本内容(注:不是插入内容,Text里面不仅可以插入文本) |
see(index) | 滚动Text,使位于index的文本可见 |
edit_redo() | 重做,需设置undo=True |
edit_undo() | 撤销,需设置undo=True |
edit_reset() | 清空文本操作记录 |
edit_separator() | 插入撤销分隔 |
index(index) | 将index的位置以line.column返回 |
replace(index1, index2, chars, *args) | 将index1到index2的内容替换为chars字符串,*args设定tag |
search(pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None) | 在index到stopindex的文本之间搜索pattern字符串 |
除了这些方法外,还有一些tag, mark, image之类的方法,放在后面讲。
wrap参数设置Text的换行方式,可以是"none"(不自动换行), "char"(按字符换行), "word"(按单词换行)。
设置为"none"时,如果字符数量超过Text的宽,不会进行换行,Text会进行滚动,以适应光标位置。
设置为"char"时,字符数量超过Text的宽,会换到下一行。
设置为"word"时,字符同样会换行,但是换到下一行的是一个完整的单词。
from tkinter import *
root = Tk()
text = Text(root)
text.pack()
mainloop()
上面的代码创建一个Text,可以在Text里面输入内容。
用户可以在Text中进行撤销和重做操作。开启撤销和重做操作,首先要设置undo=True,然后用户可以按Ctrl+Z来撤销。
text = Text(root, undo=True)
edit_undo和edit_redo方法用于撤销和重做,edit_undo方法执行一次撤销操作,edit_redo方法执行一次重做操作。如果没有内容可撤销或重做会报错。如下示例:
from tkinter import *
root = Tk()
text = Text(root, undo=1)
text.pack()
Button(root, text="Undo", command=text.edit_undo).pack()
Button(root, text="Redo", command=text.edit_redo).pack()
mainloop()
但是测试的时候,会发现:每当换行或粘贴文本的时候,才会认为这是进行了一次文本操作。撤销的时候,没能按照输入字符进行撤销。这是因为Text设置了自动加入撤销分隔,自动插入的方式和我们的期望不同。要实现按字符撤销,需要手动加入撤销分隔。
首先需要设置自动加入撤销分隔为False,也就是autoseparators=False。然后绑定
from tkinter import *
root = Tk()
text = Text(root, undo=True, autoseparators=False)
text.pack()
text.bind("", lambda e: text.edit_separator())
Button(root, text="Undo", command=text.edit_undo).pack()
Button(root, text="Redo", command=text.edit_redo).pack()
mainloop()
运行后,发现成功按照字符撤销。
Text指定字符位置的索引比较特殊,下面介绍一下Text的索引。
表达式 | 作用 | 示例 |
"+ %d chars"%count | 索引往后移动count个字符 | "1.0+ 2 chars"为"1.2"位置 |
"- %d chars"%count | 索引往前移动count个字符 | "1.2- 2 chars"为"1.0"位置 |
"+ %d lines"%count | 索引向后移动count个字符 | "1.0+ 2lines"为"3.0"位置 |
"- %d lines"%count | 索引向前移动count个字符 | "3.0- 2lines"为"1.0"位置 |
" linestart" | 索引移动到这一行的起始处,表达式前需用空格隔开 | "1.5 linestart"为"1.0"位置 |
" lineend" | 索引移动到这一行的末尾处,表达式前需用空格隔开 | "1.5 lineend"为"1.end"位置 |
" wordstart" | 索引移动到这个单词(非空白字符组成的整体)的起始处,表达式前需用空格隔开 | 如Text内容为"python tkinter",那么"1.4 wordstart"为"1.0"位置 |
" wordend" | 索引移动到这个单词(非空白字符组成的整体)的末尾处,表达式前需用空格隔开 | 如Text内容为"python tkinter",那么"1.4 wordend"为"1.6"位置 |
如想要根据一个特殊的索引,比如"insert", "@1, 2 + 2l"来获取准确的line.column式索引,可以使用index方法。
Text.index(index)
此方法返回index的line.column形式索引。
insert方法可以在Text中插入文字。
insert(index, text, *tag)
在index位置插入text内容。*tag是文本的tag标记,把这一串文字标记为tag, 后面会介绍tag。
需要注意的是,insert方法只能插入文字,而delete方法不仅可以删除文字,还可以删除其他的组件或图片。
Text可以使用image_create方法插入图片。
Text.image_create(index, cnf={}, **kw)
index是插入的索引位置,**kw参数可以是:
参数 | 作用 |
align | 设置图像的对齐方式,可以是"top", "center", "bottom"或"baseline" |
image | 设置插入的图像,是一个PhotoImage或BitmapImage |
name | 图像的名称,一般不需要指定 |
padx | 图像的x方向间距 |
pady | 图像的y方向间距 |
示例如下:
from tkinter import *
root = Tk()
image = PhotoImage(file="monster.gif")
text = Text(root)
text.pack()
text.insert("end", "插入图片")
text.image_create("end", image=image)
mainloop()
与图片相关的方法还有如下:
image_cget(index, option)
返回index位置的图像的option选项值
image_configure(index, cnf={}, **kw)
设置index位置的图像的选项值。
image_names()
返回嵌入Text的所有图像名称。
window_create方法可以在Text中插入组件。
window_create(index, cnf={}, **kw)
**kw参数可以是:
参数 | 作用 |
align | 设置组件的对齐方式,可以是"top"(上), "center"(中), "bottom"(下)或"baseline"(基线) |
create | 传递一个回调函数,函数须返回一个Text的子组件用于插入Text |
window | 设置插入的组件,必须是Text的子组件,window和create参数指定一个即可 |
stretch | 当行高大于组件高度时,是否延伸组件的高,默认为False |
padx | 组件的x方向间距 |
pady | 组件的y方向间距 |
下面两个示例,效果都是一样的。
from tkinter import *
root = Tk()
text = Text(root)
text.pack()
b = Button(text, text="MyButton")
text.window_create("end", window=b)
mainloop()
from tkinter import *
root = Tk()
text = Text(root)
text.pack()
def create_button():
b = Button(text, text="MyButton")
return b
text.window_create("end", create=create_button)
mainloop()
在Text中,可以记录一个索引的位置,在此处做一个标记,也就是mark。mark标记的位置可以在索引中使用。有两个事先定义好的mark,即"current"和"insert",参见上文。需要注意的是:"end"并不是一个mark,而是一个比较特殊的索引。
添加一个mark,需要使用mark_set方法,这个方法不仅可以添加mark,也可以更改定义过的mark。
Text.mark_set(markName, index)
在index的位置定义一个mark,名字为markName。定义了mark后,可以在索引中使用。
from tkinter import *
root = Tk()
text = Text(root)
text.pack()
text.insert("end", "123456789")
text.mark_set("myMark", "1.1") #定义一个mark,并设置位置
text.insert("myMark", "M") #在自定义的mark处插入"M"
mainloop()
如图,"M"插入到了1.1的位置。
如果想要删除mark,可以使用mark_unset方法。
Text.mark_unset(*markNames)
你可以给定一系列的markName,删除它们。但是不能删除"current"和"insert"这两个特殊mark。
如果mark附近的文本内容改变,mark也会跟着移动。如果你不理解mark的移动方式,不妨在光标旁边的文本试一下改变它们的内容,看insert标记是如何移动的。
在mark位置插入文本的时候,mark默认会往右边移动一个字符,如果想要让mark在插入时改变移动方向,可以使用mark_gravity方法。
Text.mark_gravity(markName, direction=None)
markName指定mark的名称,direction指定mark的移动方向。默认是"right",也可以设为"left"(左),设置为None则返回direction。
还有一些关于mark的用法:
mark_names()
返回Text中所有mark的名称,包括"current"和"insert"。
mark_next(index)
返回在index位置后面的一个mark的名字,不存在返回空字符串。
mark_previous(index)
返回在index位置前面的一个mark的名字,不存在返回空字符串。
Mark是对于一个索引进行记录,而Tag是对于一段文本进行记录。并且记录的这一段文字还可以进行特殊的操作,比如更改字体,更改颜色,甚至还可以进行事件绑定。
Text有一个特殊的tag叫做sel,代表选中的内容。Text对于选中内容会进行高亮显示,就是利用了sel这个tag。上文介绍过,insert插入的内容可以直接指定tag的名称。
如要自定义一个tag,须使用tag_add方法。
Text.tag_add(tagName, index1, *args)
作用:添加一个名为tagName的tag,位置是index1+*args。*args允许你提供多个位置。比如:添加一个tag,位置是1.0-1.3, 2.0-2.3,那么可以写作tag_add("tagName", 1.0, 1.3, 2.0, 2.3);如果位置是1.0-1.3, 2.0,那么以写作tag_add("tagName", 1.0, 1.3, 2.0)。
添加完了tag,可以用tag_config方法对tag的文本进行样式更改。这些参数的值也可以用tag_cget来获取
Text.tag_config = Text.tag_configure(tagName, cnf=None, **kw)
Text.tag_cget(tagName, option)
**kw给定的参数如下,用来设置tag范围内的文本。
参数 | 作用 |
borderwidth | 文本的边框的宽度 |
relief | 文本的relief |
background | 文本的背景色 |
bgstipple bg |
使用一个位图作为背景,并使用background指定的颜色填充 |
foreground | 文本的前景色 |
fgstipple fg |
使用一个位图作为前景,并使用foreground指定的颜色填充 |
font | 文本的字体 |
justify | 文本的对齐方式,可以是"left", "right", "center",需先指定tag为该文本行的第一个字符 |
offset | 文本相对于基线的偏移距离,升高文本则为正数(基线:一般在文本底部的一条基准线,类似于英文四线三格的第三条线) |
underline | 是否添加下划线,默认为False |
overstrike | 是否添加删除线,默认为False |
wrap | 换行方式 |
如下示例:
from tkinter import *
root = Tk()
text = Text(root)
text.pack()
text.insert("end", "123456789")
text.tag_add("tag", "1.0", "1.4")
text.tag_config("tag", background="yellow", overstrike=True)
mainloop()
tag可以进行事件绑定,需通过tag_bind方法。相对地,也有用于解除绑定的tag_unbind方法。
tag_bind(tagName, sequence, func, add=None)
tag_unbind(tagName, sequence, funcid=None)
tag_bind在tagName标记的文本处绑定sequence事件,回调func。比如text.tag_bind("mytag", "
from tkinter import *
from webbrowser import open as webopen #webbrowser.open用来启动浏览器
root = Tk()
text = Text(root)
text.pack()
text.insert("end", "进入CSDN", "link") #插入内容并设置tag为"link"
text.tag_config("link", foreground="blue", underline=1)
text.tag_bind("link", "", lambda x:webopen("https://www.csdn.net"))
mainloop()
如果tag的位置之间发生重合,一段文本就有可能有多个tag。tag之间有优先级,多个tag的文本选项以较优先的tag为准。但如果较优先的tag中有一部分选项没有设置,那么就设置为较低tag的选项。比如一段文本有两个tag,tag1较优先,tag2优先级较低,此时设置tag1中(foreground="red", background=None),而tag2中(foreground="red", background="yellow"),那么整个段落的颜色则为(foreground="red", background="yellow")。
tag_raise和tag_lower方法分别可以提高tag的优先级和降低tag的优先级。
Text.tag_raise(tagName, aboveThis=None)
如果不指定aboveThis,则将tagName优先级提升至最高。如果指定aboveThis,则将tagName优先级提升至名为aboveThis的tag之上。
Text.tag_lower(tagName, belowThis=None)
如果不指定belowThis,则将tagName优先级降至最低。如果指定belowThis,则将tagName优先级降至名为belowThis的tag之下。
文本删除tag可以使用tag_remove方法。
Text.tag_remove(tagName, index1, index2=None)
删除tag需要指定tag的名称,还需要指定删除的范围,从index1到index2之间,将tag删除。
此外,还有一些用于tag操作的方法:
tag_names(index=None)
返回所有tag的名称,index指定位置。
tag_ranges(tagName)
返回所有tagName标记的文本以及位置信息。
tag_nextrange(tagName, index1, index2=None)
返回index1至index2之间第一个有tagName的位置。
tag_prevrange(tagName, index1, index2=None)
tag_nextrange反过来查找,返回最后一个有tagName的位置。
get方法用于返回Text的文本内容的字符串,而不能返回其他插入的组件或图片。
Text.get(index1, index2=None)
返回index1到index2两个位置之间的文本。
如果还需要返回其他插入的组件或图片,就需要使用dump方法。
Text.dump(index1, index2=None, command=None, **kw)
index1和index2是获取的范围,这个方法会返回一个列表,列表的每个项目都是一个类型的插入内容,是一个三项元组。
from tkinter import *
root = Tk()
text = Text(root)
text.pack()
text.tag_config("MyTag", background="blue")
image = PhotoImage(file="monster.gif")
window = Button(text, text="这是一个按钮组件")
text.insert("end", "这是一段普通的文字")
text.insert("end", "这是一段tag文字", "MyTag")
text.image_create("end", image=image)
text.window_create("end", window=window)
mainloop()
上面的代码运行效果如图,如果再打印出text.dump("1.0", "end")获取text的内容,得到这样的输出:
下面详解dump返回列表中的每个元组的项的含义。第一项表示插入内容的类型,第二项表示插入内容的信息,第三项表示的是插入内容的位置。
插入内容类型(第一项) | 第一项解释 | 第二项解释 |
text | 文本 | 表示插入的文本 |
tagon | 标签的起始 | 表示tag名称 |
tagoff | 标签的结束 | 表示tag名称 |
mark | mark标记 | mark的名称 |
image | 图片 | 表示插入的图片对象的名称,name参数可设定 |
window | 组件 | 表示插入的组件对象的名称,name参数可设定 |
注:由于dump返回的插入组件是组件的名称,是一个字符串,不方便直接对组件对象进行操作。如果你还记得Misc类中讲解的nametowidget方法,可以使用这个方法将组件名称转换成组件对象。
search方法用于在Text中搜索某段文本。
Text.search(pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None)
这个方法返回搜索到的第一段文本的第一个字符的位置。参数及作用如下:
参数 | 作用 |
pattern | 需要在Text内容中搜索的文本 |
index | 起始搜索位置 |
stopindex | 结束搜索位置(默认为最后) |
forwards | 由前往后查找,默认为True |
backwards | 由后往前查找,和forwards可指定一个 |
exact | 搜索与pattern完全匹配的文本,和regexp, nocase指定一个 |
regexp | 将pattern解释为正则表达式匹配,和exact, nocase指定一个 |
nocase | 搜索忽略大小写,和exact, regexp指定一个 |
count | 是一个IntVar,存储搜索结果的文本字符数量 |
tkinter有两种图片对象,一种是PhotoImage,用于导入*.gif, *.ppm, *.pgm格式的文件,新版tk还支持*.png;还有一种是BitmapImage,用于导入*.xbm的位图格式文件。这些图片对象都可以被传递给组件的image参数。这些图片对象都支持以下方法:
方法 | 作用 |
config(**kw) | 更改图片参数设置 |
height() | 返回图片的高 |
width() | 返回图片的宽 |
type() | 返回图片的类型,"photo"或"bitmap" |
PhotoImage(name=None, cnf={}, master=None, **kw)
name用来设定图片的名称。此外,PhotoImage支持以下关键字参数。
参数 | 作用 |
data | 将图像的数据内容以字符串传递;字符串可以是二进制数据或base64编码数据(支持PNG和GIF);如同时指定了data和file参数,优先使用file指定的图片 |
file | 指定图片文件名称 |
format | 指定文件格式名 |
gamma | 图像的伽马值,可以理解为亮度;默认值为1,指定的值必须大于0 |
height | 图像的高度 |
width | 图像的宽度 |
palette | 指定要分配用于显示此图像的颜色立方体的分辨率,因此指定从显示它的窗口的颜色图中使用的颜色数。调色板规范字符串可以是一个十进制数,指定要使用的灰色阴影数,也可以是由斜线 (/) 分隔的三个十进制数,分别指定要使用的红色、绿色和蓝色阴影数。 如果使用第一种形式(单个数字),图像将以单色(即灰度)显示 |
除上描述的方法外,还支持以下方法:
方法 | 作用 |
blank() | 将图片设为完全透明 |
cget(option) | 获取option参数的值 |
copy() | 复制图片,返回新的图片对象 |
zoom(x, y="") | 返回原图像在x方向缩放至原来x倍,y方向缩放至原来y倍的图像;如不指定y,则y同x |
subsample(x, y="") | 将图片在x方向缩放至原来x分之一的大小,y方向缩放至原来y分之一的大小;如果x为负数,则图像垂直翻转;如果y为负数,则图像水平翻转;如不指定y,则y同x |
get(x, y) | 返回在x, y像素位置上的颜色元组(red, green, blue) |
put(data, to=None) | 从to位置的像素点开始向设置右方像素的颜色;data需提供[(color, color, ...), (color, color, ...), ...]这样的形式,列表中每一个项都表示一行,每一个项中间设定了这一行需改变的像素点颜色 |
write(filename, format=None, from_coords=None) | 将图像写入filename文件,图片格式为format;from_coords指定写入的图像范围,可以是(x1, y1, x2, y2)表示一个矩形范围,或是(x1, y1)表示从一个点的位置到图片右下角,也可以不指定表示整个图像 |
transparency_get(x, y) | 返回一个布尔值,根据位于x, y的像素点是否透明 |
transparency_set(x, y, boolean) | 将x, y的像素点是否透明的状态设为boolean |
BitmapImage(name=None, cnf={}, master=None, **kw)
name用于设定图片的名称,此外还可以设置如下关键字参数:
参数 | 作用 |
data | 将图像的数据内容以字符串形式传递;字符串必须遵循X11位图格式;如同时指定了data和file参数,优先使用data指定的图片 |
file | 指定图片文件名称 |
background | 设置位图的背景色 |
foreground | 设置位图的前景色 |
maskdata | 将位图掩码的数据内容以字符串形式传递 |
maskfile | 指定位图掩码文件名称 |
BitmapImage不支持除上面描述的公共方法外的其他方法。
下一篇:Python tkinter(GUI编程)模块全解(下)_Python zzy的博客-CSDN博客
如果你在开发Python tkinter程序时遇到了问题,或是有文章内容的建议,可以私信联系我,感谢支持!