Button
可以从两方面熟悉button:自身实现(外观和属性)、交互(事件处理)。
自身实现
1、文本和图标相关
-
text: 设置按钮上显示文本的内容
-
image: 设置按钮显示图像
-
compound: 文本与图片的组合方法. 例如:left 图像位于文本左边.
-
underline: 设置按钮文本某个字符是否有下划线。
-
cursor:通过设置
cursor
属性,你可以指定不同类型的光标。常用的光标类型有:"arrow"
:标准的箭头光标(默认光标)。"hand"
:手形光标1"hand1"
:手形光标2"hand2"
:手形光标3"cross"
:十字形光标。"wait"
:表示正在等待的旋转光标。"text"
:表示文本输入的光标(通常在文本框中使用)。"circle"
:圆形光标。"plus"
:加号形状的光标。"star"
:星形标。
2、布局和样式
-
width: 按钮的宽度
-
height: 按钮的高度
-
padx: 按钮左右的内边距
-
pady: 按钮上下的内边距.
-
anchor:控制文本的位置。可选值如
W
,E
,N
,S
,CENTER
等,指定文本的位置。 -
borderwidth
或bd
: 按钮的边框宽度。 -
relief
: 按钮的边框样式。常见的值有:-
RAISED
:凸起的按钮(默认)。 -
SUNKEN
:凹陷的按钮。 -
FLAT
:没有边框的按钮。 -
GROOVE
:雕刻的边框。 -
RIDGE
:脊状的边框。
-
常见支持 relief
属性的控件包括:Button
、Label
、Entry
、Text
、Frame
、Canvas
、Listbox
、Scrollbar
、PanedWindow
、Checkbutton
和 Radiobutton
等。
3、字体和颜色
-
font
: 设置按钮文本的字体样式,如("Arial", 12, "bold")
。 -
fg
或foreground
: 按钮文本的颜色。 -
bg
或background
: 按钮的背景颜色。 -
activebackground
: 按钮在被按下时的背景颜色。 -
activeforeground
: 按钮在被按下时的文本颜色。 -
highlightbackground
: 按钮获得焦点时的背景颜色。 -
highlightcolor
: 按钮获得焦点时的边框颜色。 -
highlightthickness
: 按钮焦点边框的厚度。
4、事件和行为
-
command
: 按钮点击时执行的回调函数。 -
state
: 按钮的状态。常见值有:-
NORMAL
:正常状态 -
DISABLED
:禁用状态(不可点击)。 -
ACTIVE
:按下状态(按钮按下时显示)。
-
-
repeatdelay
: 设置按钮按住后首次重复回调的延迟时间(以毫秒为单位)。 -
repeatinterval
: 设置按钮按住后,每次回调之间的时间间隔。
设想一个场景,按住按钮1分钟不放,回调函数是怎样触发频率,例如开枪射击场景...
repeatdelay与repeatinterval就是为了解决这个问题.
假如持续按住按钮1分钟,将repeatdelay设置为5秒,repeatinterval设置为1秒.按住按钮延迟(repeatdelay)5秒后第一次回调,后续每间隔(repeatinterval)1秒回调一次.若按按钮时间不足5秒就释放,会回调一次.
5、焦点相关
-
takefocus
: 是否允许按钮获取焦点。默认值为True
,可以设置为False
禁止获取焦点。 -
focus()
: 设置按钮为当前焦点。 -
focus_set()
: 将焦点设置到按钮上。
焦点是个什么概念,为了解决什么问题?
主要是为了提高交互体验感.
焦点是指哪个控件当前可以接收键盘输入或键盘事件.注意,不包括鼠标事件.
在表单、数据输入、或者快捷键触发操作的场景中,focus_set()
可以用来设置用户交互的起点。
交互
关于button的交互有两种实现方法:调用回调函数 、绑定事件.
事件绑定在后续讨论
案例
点击按钮3秒后,按钮变的不可用
import time
from tkinter import *
from tkinter import messagebox
# ----------------- 创建窗口 -----------------
root = Tk()
# 系统桌面大小
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
# 设置窗口大小
x = int(screenwidth/4)
y = int(screenheight/4)
width = int(screenwidth/2)
height = int(screenheight/2)
root.geometry(f'{width}x{height}+{x}+{y}')
# ----------------- 按钮 -----------------
cnt = 0
msg_label = None
# 展示消息
def set_msg(widget, msg):
global msg_label
if msg_label:
msg_label.destroy()
msg_label = Label(widget, text=msg)
msg_label.pack()
# 重置按钮状态
def set_config():
button.config(state="disable",text="不可用",cursor="wait")
# 按钮事件
def get_button():
global cnt
cnt = cnt + 1
msg1 = f'按钮第 {cnt}次被点击. 状态: {button.cget("state")} \n3秒后 按钮将不可用!'
set_msg(root, msg1)
"""
after不会阻塞主事件循环,会在指定的时间后调用一个回调函数,而不会影响程序的其他操作(例如用户的鼠标点击、键盘输入等)。
单位毫秒,1s=1000毫秒
使用sleep.time(3) 会阻塞主循环,出现卡顿情况.
设置多个after,相互不影响
"""
root.after(3000, set_config) # 3秒后重置属性
msg2 = f'按钮已不可用!'
"""
after第二个参数是回调函数名
若不要lambda关键字,则会立即调用set_msg(root, msg2),窗口出现卡顿现象.
lambda 的作用是延迟执行 set_msg(root, msg2),并且传递必要的参数。
具体来说,lambda 使得 set_msg(root, msg2) 不会立即执行,
而是等到 after 指定的延迟时间(在这个例子中是 3 秒)后执行。
"""
# root.after(3000, lambda: set_msg(root, msg2))
# 或者 定义一个中间函数
def exe_set():
set_msg(root, msg2)
root.after(3000, exe_set)
button = Button(root, text="我是按钮", activeforeground='red',
cursor="hand2", command=get_button,
repeatdelay=5000, repeatinterval=100)
# 设置
button.focus()
button.pack()
root.mainloop()
案例知识点:
- 可以使用button.config() 重设属性.button.cget()获取属性值; 亦可将button看成字典,操作属性值
- after方法: after(延迟时间, 回调函数名). 避免主窗口卡顿; 但如果after中回调函数耗时长还是会阻塞主窗口程序,因为
tkinter
的主事件循环是单线程的。需要使用子线程解决. - lambda: 传递参数
总结:
button这个知识点中,较常用的:设置焦点、after方法避免阻塞、lambda执行传参函数