The most complete tutorial of Python tkinter (GUI programming) module (in)

Previous: Python tkinter (GUI programming) module full solution (on)_Python zzy's blog-CSDN blog

2 tkinter main module

2.10 Checkbutton

Checkbutton is a multi-selection box, the user can check or uncheck. Checkbutton can bind a variable, usually BooleanVar. In addition to the parameters of Button, Checkbutton can also have some other parameters.

References: Python --- (3) Tkinter window component: Checkbutton_Myopia's down-to-earth blog-CSDN blog

Checkbutton(master=None, **kw)

parameter effect
variable Variable related to Checkbutton selection
onvalue The value of variable when the multi-select box is selected, the default is 1
offvalue The value of variable when the checkbox is not selected, the default is 0
selectcolor Choose the color of the box
selectimage The picture when selected (the image parameter must be specified)
indicatoron Whether to display a checkbox style, the default is True

Common methods: 

method effect
select() Check the checkbox
deselect() uncheck the box
toogle() Toggle the selected state of the checkbox (invert the checkbox)
invoke() Call the command of Checkbutton (disabled invalid)
flash() Make the Checkbutton blink several times (switch between normal and active several times)

Create Checkbutton

from tkinter import *

root = Tk()
root.geometry("200x200")

def tg():
    print("选中/取消选中")

cb = Checkbutton(root, text="toogle", command=tg)
cb.pack()

mainloop()

 

You can try to click the Check button, and the box on the left will be checked or unchecked. "Checked/Unchecked" is printed after each selection.

variable parameter

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()

Bind the multi-selection button to a Var so that the value of the Checkbutton can be obtained.

indicatoron parameter

Checkbutton has two styles, one is the check box style above, and it can also be set as a button box style. The default is to display the style of a check box. If indicatoron is set to False, it can also be set to the style of a button.

from tkinter import *

root = Tk()
root.geometry("200x200")

cb = Checkbutton(root, text="toogle", indicatoron=False)
cb.pack()

mainloop()

 Selected state >>>

2.11 Radiobutton

Corresponding to the multi-selection box, Radiobutton is a radio button. Multiple radio buttons can be bound to a variable, and the value of this variable is the value of the selected radio button.

References: Python --- (4) Tkinter window component: Radiobutton_Myopia's down-to-earth blog-CSDN blog

Radiobutton(master=None, cnf={}, **kw)

The parameters of Radiobutton are almost the same as those of Checkbutton. The difference is that Radiobutton does not have the two parameters of onvalue and offvalue, but is replaced by the parameter value. The role of the value parameter is to specify the value of Var bound when the radio button is selected.

The commonly used methods are basically the same as those introduced by Checkbutton, but there is no toogle method.

Create Radiobuttons

In general, there will be multiple Radiobuttons, but only one 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()

The above three radio buttons are all bound to a variable, and a value parameter is also specified. When the value of the variable is set to the value of the checkbox, the checkbox will be selected. When a radio button is clicked, the value of the variable is set to the value of the radio button. Because the variable can only have one value, you can only select one radio button in the radio button bound to the variable.

2.12 Menu

Menu is also the menu. There are generally two types of menus, one is the menu on the window, and the other is the pop-up menu.

References: Python --- (thirteen) Tkinter window components: Menu_Myopia's down-to-earth blog-CSDN blog 

Menu(master=None, cnf={}, **kw)

parameter effect
tearoff Whether to allow the user to detach the menu, the default is True
title Detach the title of the menu
tearoffcommand Event executed when the user detaches the menu
postcommand Event executed when the menu is opened

Common methods:

method effect
add(itemType, **kw) Add a menu item, itemType is one of command, cascade, checkbutton, radiobutton, separator
insert(index, itemType, **kw) Insert menu item at index position
add_command(**kw) Add command menu item
add_cascade(**kw) Add hierarchical menu items
add_checkbutton(**kw) Add a multi-select menu item
add_radiobutton(**kw) Add radio button menu item
add_separator(**kw) Add menu divider
delete(index1, index2=None) Delete the menu item located at index1 (to index2)
entrycget(index, option) Get the option value of the menu item at index
entryconfig(index, **kw) Change the value of the parameter located in the index menu item
post(x, y) popup menu at (x, y) position
unpost() cancel popup menu
invoke(index) Execute the command located in the index menu item, and select them if the menu items are radio or multi-selection boxes.
type(index) Returns the type of the menu item at index, which is one of command, cascade, checkbutton, radiobutton, separator

Create window menu

from tkinter import *

root = Tk()

menubar = Menu(root)
root.config(menu=menubar) #把菜单绑定root

mainloop()

In this way, we have successfully created a menu and bound the displayed window. But such a menu has nothing, and then we need to add menu items to the menu.

add method

The add method can add menu items. The first parameter itemType specifies the type of menu item, which will be introduced shortly. add(itemType) can also be replaced by add_itemType(). You can also provide the following parameters **kw (activebackground, activeforeground, bg, fg are not introduced here because of the introduction of the previous components):

参数 作用
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

add_command方法

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")

add_cascade方法

菜单可以有层级之分。最上层的菜单就是绑定了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参数

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("<Control-n>", new)

mainloop()

按下Ctrl-N或点击菜单,执行new函数。

underline参数

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()

激活并按下Alt>>>按下n键>>>

add_separator方法

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("<Button-3>", show)

mainloop()

2.13 Menubutton

Menubutton是一个Button的样式,可以绑定一个菜单,点击后弹出菜单。这个组件比较老,现在可以用Menu实现Menubutton的功能了,不过Menubutton在某些情况下要更简单好用一些。

参考资料:Python ---(十四)Tkinter窗口组件:Menubutton_近视的脚踏实地的博客-CSDN博客

Menubutton(master=None, cnf={}, **kw)

参数和Button基本一样,但是没有command,还有一些其他的参数。

参数 作用
menu 绑定一个菜单
direction 位于按钮的菜单弹出方位,有"left"(左),"right"(右),"above"(上),"below"(下),默认是below

创建Menubutton

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,否则菜单跳不出来。 

2.14 组件基类

现在,你已经学习了一部分组件。在学习更多组件之前,先要详细介绍一下组件的基类。在tkinter(Python)中,大多数组件都有共用的方法,这是因为它们都继承共同的类。如果你想自己了解一下继承关系,可以看Lib/tkinter/__init__.py。

在这些类中,有一些方法的参数默认为None,这意味着如果为None可以返回当前参数设定的值。

Misc类

这个类是模块中最基本的类,所有组件甚至是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()不需要。

Wm类

参考资料: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格式有以下几种:

  • "%dx%d"%(width, height):设置窗口的宽和高。
  • "+%d+%d"%(left, top):设置窗口与屏幕左边、上边的距离。
  • "+%d-%d"%(left, bottom):设置窗口与屏幕左边、下边的距离。
  • "-%d-%d"%(right, bottom):设置窗口与屏幕右边、下边的距离。
  • "-%d+%d"%(right, top):设置窗口与屏幕右边、上边的距离。
  • "":设置为空字符串,表示窗口大小适应内部组件大小。
  • 也可以将窗口宽高与窗口偏移距离结合使用,如"100x100+50-30"表示:窗口大小100x100,与屏幕左边相隔50像素,与屏幕下边相隔30像素。

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方法相反。

2.15 Listbox

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() 返回列表框中选项数量

创建Listbox

from tkinter import *

root = Tk()

lb = Listbox(root)
lb.pack()

mainloop()

 

这样就创建了一个Listbox,不过里面什么项目也没有。

虚拟事件<<ListboxSelect>>

Listbox中有项目选中时会产生一个虚拟事件<<ListboxSelect>>,可以被bind捕捉到。

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("<<ListboxSelect>>", select)

mainloop()

 

如图示,选中项目时会打印选中的项目索引。

see方法

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()

2.16 Scrollbar

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之间的浮点数,代表占整个滚动条的比例

创建Scrollbar

from tkinter import *

root = Tk()

sb = Scrollbar(root)
sb.pack(side="right", fill="y")

mainloop()

这段代码在屏幕右侧绘制了一个滚动条。这个滚动条没有绑定任何可滚动的组件,所以没有任何用处。在映射滚动条时,通常会加入fill="y"这个参数,让滚动条完全伸展开,方便拖拽(在水平滚动条中是fill="x",grid布局则要指定sticky)。

XView和YView类

在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参数

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()

运行效果:

2.17 Message

Message是一个比较少用的组件,功能基本可以被Label替代。Message组件可以自动换行,指定Label组件的wraplength也可以达到这个功能,不过Message可能更加简便一些。

参考资料:Python ---(十六)Tkinter窗口组件:Message_近视的脚踏实地的博客-CSDN博客

Message(master=None, cnf={}, **kw)

参数和Label基本一样,但有一个参数aspect,表示组件达到多少像素换行。

2.18 Scale

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的值

创建Scale

from tkinter import *

root = Tk()

scale = Scale(root)
scale.pack()

mainloop()

用户可以拖动滑块,设定滑块的值。

from_和to参数

设置这两个参数可以设定拖拽的最小和最大值。

from tkinter import *

root = Tk()

scale = Scale(root, from_=10, to=30)
scale.pack()

mainloop()

 

滑块只能从10拖动到30。

tickinterval参数

tickinterval参数使Scale可以添加刻度数值。如from_=0, to=100, tickinterval=10的Scale:

垂直的Scale的刻度显示在左边,水平的Scale则显示在下面。

label参数

label参数可以显示在Scale旁边显示一个标签。例如:label="拖动滑块":

垂直的Scale的标签在右边,水平的Scale则在显示上面。 

resolution参数

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()

2.19 Spinbox

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。 

创建Spinbox

from tkinter import *

root = Tk()

spinbox = Spinbox(root)
spinbox.pack()

mainloop()

由于没有指定from_, to或values,所以箭头按了也无效。

from_, to和increment参数

如设置from_=0, to=10,那么点击上下箭头的时候,文本框里面的内容会在0到10之间调节。但用户仍然可以在Spinbox中输入任何内容。

increment参数指定点击箭头的步长,类似于Scale组件的resolution参数选项。

values参数

values参数和上面的from_, to, increment只能指定一边。values参数传递一个元组之类的序列。比如values=("Python", "C", "Java", "Tcl"),那么点击上下箭头的时候,文本框中的内容会在元组里面切换。

readonly状态

Spinbox可以设置为readonly状态,和Entry一样。设置为readonly的时候,文本框中不能输入,但是仍可以通过按上下箭头调节Spinbox的值。

2.20 OptionMenu

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选项值

创建OptionMenu

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方法。

2.21 PanedWindow

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() 返回子组件的列表

创建PanedWindow

from tkinter import *

root = Tk()

w = PanedWindow(root, orient="horizontal")
w.pack(fill="both", expand=True)

mainloop()

这段代码创建了一个空的水平方向PanedWindow,需要在里面添加组件才能看出来。 

add方法

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参数

showhandle参数如果设置为True,将会在分割线的位置添加一个手柄。用户可以拖拽这个手柄,这样可以方便地调整窗格的大小。

手柄是一个正方形。

2.22 Text

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参数

wrap参数设置Text的换行方式,可以是"none"(不自动换行), "char"(按字符换行), "word"(按单词换行)。

设置为"none"时,如果字符数量超过Text的宽,不会进行换行,Text会进行滚动,以适应光标位置。

设置为"char"时,字符数量超过Text的宽,会换到下一行。

设置为"word"时,字符同样会换行,但是换到下一行的是一个完整的单词。

创建Text

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。然后绑定<Key>,每当输入一个字符调用edit_separator()方法进行手动撤销分隔。如下示例:

from tkinter import *

root = Tk()

text = Text(root, undo=True, autoseparators=False)
text.pack()
text.bind("<Key>", 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的索引。

  • 表示为line.column的格式:line是行数,column是列数,行数和列数之间用一个"."隔开,可以是一个浮点数或字符串。比如:第一行,第一个字符表示为"1.0"或1.0;第三行,第四个字符表示为"3.3"或3.3。行数的索引以1为开始,列数的索引以0为开始。
  • current:表示离鼠标上一次点击位置最近的一个字符。
  • insert:表示光标位置。
  • end:表示结尾的位置。
  • 表示为line.end的格式:line是行数,end代表结尾,是一个字符串。表示第line行的最后一个字符。比如:第二行最后一个字符表示为"2.end"。
  • 表示为mark的名称:mark下文介绍,如果写作mark的名称可以表示mark的位置。上面的current和insert是两个预定义的mark。
  • 表示为tagName.first/last:tag下文介绍,如果写作tag的名称加上.first表示tag的第一个字符之前,"tagName.last"表示tagName的最后一个字符之后。
  • sel.first/last:sel是一个特殊的tag,"sel.first"代表选中内容的开头字符之前,"sel.last"代表选中内容的结尾字符之后。
  • 表示为window或image的对象字符串:如果插入了某个组件或图像,可以表示为它们的字符串形式(执行str)来表示它们的位置。
  • 表示为@x, y:表示离(x, y)窗口位置最接近的字符。比如"@100, 100"表示最接近窗口位置(100, 100)的字符。
  • 位置+表达式字符串:可以在上述的索引后面加上一些特殊的表达式来指定位置,表达式的规范如下。
    表达式 作用 示例
    "+ %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 + 3 chars"写成"insert+3c"是没有问题的。 

如想要根据一个特殊的索引,比如"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()

  

Mark(标记)

在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的名字,不存在返回空字符串。

Tag(标签)

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", "<Button-1>", callback),点击一下"mytag"的tag文本即可执行callback函数。如下示例,点击tag内容会自动链接到网站。

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", "<Button-1>", 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和dump方法

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方法

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,存储搜索结果的文本字符数量

2.23 tkinter图片对象

tkinter有两种图片对象,一种是PhotoImage,用于导入*.gif, *.ppm, *.pgm格式的文件,新版tk还支持*.png;还有一种是BitmapImage,用于导入*.xbm的位图格式文件。这些图片对象都可以被传递给组件的image参数。这些图片对象都支持以下方法:

方法 作用
config(**kw) 更改图片参数设置
height() 返回图片的高
width() 返回图片的宽
type() 返回图片的类型,"photo"或"bitmap"

PhotoImage

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) Write the image to the filename file, the image format is format; from_coords specifies the range of the image to be written, which can be (x1, y1, x2, y2) representing a rectangular range, or (x1, y1) representing the position from a point to The lower right corner of the image, or not specified to represent the entire image
transparency_get(x, y) Returns a Boolean value, depending on whether the pixel at x, y is transparent
transparency_set(x, y, boolean) Set whether the pixel of x, y is transparent or not to boolean

BitmapImage

BitmapImage(name=None, cnf={}, master=None, **kw)

name is used to set the name of the picture, and the following keyword parameters can also be set:

parameter effect
data Pass the data content of the image in the form of a string; the string must follow the X11 bitmap format; if both data and file parameters are specified, the image specified by data will be used first
file specify image file name
background Set the background color of the bitmap
foreground Set the foreground color of the bitmap
maskdata Pass the data content of the bitmap mask as a string
maskfile Specifies the bitmap mask file name

BitmapImage does not support methods other than the public methods described above. 

Next: Python tkinter (GUI programming) module full solution (Part 2)_Python zzy's Blog-CSDN Blog

If you encounter problems when developing Python tkinter programs, or have suggestions for article content, you can contact me by private message, thank you for your support!

Guess you like

Origin blog.csdn.net/qq_48979387/article/details/125806479