测试tkinter绑定事件的小工具

6 篇文章 0 订阅

tkinter是安装python后自带的一个GUI库,并不是很好用,但是好就好在这个GUI库是安装自带的。笔者比较喜欢wxPython,但是还需要单独安装。

想要了解tkinter的绑定事件,可以查看tkinter的帮助文档,具体运行这么一段代码就可以看到:

import tkinter as tk

help(tk.Tk.bind)

其中有一段介绍:

An event pattern is of the form <MODIFIER-MODIFIER-TYPE-DETAIL>

TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave

容我吐槽一下,这个帮助文档甚至还有错误,有一些该有逗号的地方(比如“Gravity Reparent”)中间也没有逗号,并且也没有处在文档的换行位置。初学者看了还以为是一个事件的名字,实际上是两个事件。

(关于这一点,还可以在idlelib.multicall库的_types参数看到关于事件的定义,可以证明这一点)

随后写了一个测试小组件的所有事件的响应效果的程序,代码如下:

import re
import tkinter as tk

# help(tk.Tk.bind)

__doc__ = '''Activate, Enter, Map,
    ButtonPress, Button, Expose, Motion, ButtonRelease
    FocusIn, MouseWheel, Circulate, FocusOut, Property,
    Colormap, Gravity Reparent, Configure, KeyPress, Key,
    Unmap, Deactivate, KeyRelease Visibility, Destroy,
    Leave'''

events = re.findall(r'\w+', __doc__)
print(len(events))

events_used = []

def callback(ename):
    def f(e):
        if ename not in events_used:
            events_used.append(ename)
            print('%02d'%len(events_used), ename.ljust(15), e)
    return f

top = tk.Tk()
txt = tk.Text(top)
for ename in events:
    txt.bind('<%s>'%ename, callback(ename))
txt.pack(fill='both', expand=1)
# tk.Button(top, text='forget', command=lambda: txt.forget()).pack()
top.mainloop()

nouse = [ename for ename in events if ename not in events_used]
print('Not use:')
print(nouse)
print(len(nouse))

方法很简单,首先通过正则表达式的方法获取到帮助文档中提到的所有事件名,总共有25种事件。

不过其中的“Button”和“ButtonPress”是一样的,“Key”和“KeyPress”是一样的,所以实际上是有23种事件。

然后逐一绑定到tkinter的Text控件上,在出现事件的时候打印事件名和事件类。

不过类似于<Motion>这样的事件会很容易触发,为了避免刷屏,我用一行代码:

if ename not in events_used:
    # print log ...

控制事件只在第一次触发的时候打印。如果希望持续打印输出,把这里改成:

if ename not in events_used or True:

就可以不断显示。

事件触发的条件大部分比较好理解,详细的解释在这一篇文章里也有介绍,可以看看:《python | tkinter(六) bind事件信息》

其中<Visibility>会在从最小化恢复窗口的时候触发,<Expose>会在窗口激活且显示面积增加(减少不会),比如恢复窗口和在窗口边缘移动的时候触发。

<Unmap>事件可以通过取消放置,在控件运行txt.forget()函数的时候会触发,不过在最小化的时候也会触发。(所以我把那段代码注释掉了)

运行的事件记录大概像这个样子:

01 Configure       <Configure event x=0 y=0 width=564 height=316>
02 Map             <Map event>
03 Visibility      <Visibility event state=VisibilityUnobscured>
04 Expose          <Expose event x=0 y=0 width=564 height=316>
05 Enter           <Enter event state=Mod1 focus=False x=556 y=173>
06 Motion          <Motion event state=Mod1 x=339 y=152>
07 Button          <ButtonPress event state=Mod1 num=1 x=208 y=153>
08 FocusIn         <FocusIn event>
09 ButtonRelease   <ButtonRelease event state=Mod1|Button1 num=1 x=208 y=153>
10 MouseWheel      <MouseWheel event state=Mod1 delta=-120 x=208 y=152>
11 Key             <KeyPress event state=Mod1 keysym=Shift_L keycode=16 x=208 y=154>
12 KeyRelease      <KeyRelease event state=Shift|Mod1 keysym=Shift_L keycode=16 x=208 y=154>
13 Leave           <Leave event state=Mod1 focus=False x=678 y=161>
14 FocusOut        <FocusOut event>
15 Unmap           <Unmap event>
16 Destroy         <Destroy event>

排除掉含义相同的**Press事件后,仍然有7个事件我没有试出来在什么情况下可以触发:

['Activate', 'Deactivate', 'Property', 'Colormap', 'Gravity', 'Reparent', 'Circulate']

如果有知道的童鞋欢迎在文章里留言告诉我测试能够展示的方法。

不过后来我看到了这一篇文章,感觉大意是说这些方法都是没用的,仅供参考:《tk中的事件类型》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值