使用 Python 3.7.3,如何禁用 Tkinter 的背景“Tab"?键绑定 [英] Using Python 3.7.3, how do I disable Tkinter's background "Tab" key binding

查看:37
本文介绍了使用 Python 3.7.3,如何禁用 Tkinter 的背景“Tab"?键绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在没有在根或帧级别明确绑定到它的情况下拦截 Tab 字符按下,因为这会增加超出预期的复杂性.我真的不想为每个按钮绑定一个简单的处理程序.

我想知道两件事:

  1. 如何拦截/禁用后台Tab"键绑定?
  2. 空格键在选项卡后触发与该按钮关联的命令(即使您在当前选项卡的不同小部件上手动调用 widget.focus_set()):我该如何防止这种情况?

出于某种原因,Tkinter 处理 Tab 键以自动前进到下一个对象.在我的情况下,我不想要这个.我还尝试了基于此 answer 的return 'break'",但它似乎不起作用,或者_get_key"" 事件处理程序发生在后台绑定之后.​​

class testFocus:btns = { }字符串 = ''NumberCharList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '句号', '逗号', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]def __init__(self, root):self.top = 根self.top.bind('', self._get_key)self.frame = tk.Frame(self.top)self.frame.pack()self.var = tk.StringVar(value='Type:')self.lbl = tk.Label(self.frame, textvariable=self.var)self.lbl.pack()对于范围内的 i (15):self.btns[i] = tk.Button(self.frame, text=f'Click {i}', command=lambda x=i: print(x))self.btns[i].pack()def _get_key(self, event):打印('Root._get_key.event.keysym:',event.keysym)打印(root.focus_get())如果 event.keysym 在 self.NumberCharList 中:self.string += event.keysymself.var.set(self.string)elif event.keysym == 'Tab':print('TAB!') # 不工作......为什么?elif event.keysym == '删除':self.string = ''self.var.set(self.string)elif event.keysym == 'BackSpace':self.string = self.string[:-1]self.var.set(self.string)# ... 处理特定按键的其他代码.打印(root.focus_get())如果 __name__ == '__main__':根 = tk.Tk()root.geometry(f"800x480+{int(root.winfo_screenwidth()/8)}+{int(root.winfo_screenheight()/6)}")root.attributes('-fullscreen', False)root.title('测试')root.resizable(宽度=假,高度=假)app = testFocus(root)root.mainloop()

标签输出:

Root._get_key.event.keysym: Tab..Root._get_key.event.keysym:选项卡.!frame.! 按钮.!frame.! 按钮Root._get_key.event.keysym:选项卡.!frame.!button2.!frame.!button2Root._get_key.event.keysym:选项卡.!frame.!button3.!frame.!button3Root._get_key.event.keysym:选项卡.!frame.!button7.!frame.!button7Root._get_key.event.keysym:选项卡.!frame.!button8.!frame.!button8Root._get_key.event.keysym:选项卡.!frame.!button9.!frame.!button9Root._get_key.event.keysym:选项卡.!frame.!button10.!frame.!button10Root._get_key.event.keysym:选项卡.!frame.!button12.!frame.!button12

解决方案

如何拦截/禁用后台Tab"键绑定?

默认选项卡行为基于对 "all" 绑定标记的绑定.您可以移除该绑定以移除默认选项卡行为.

root.unbind_all("")

根据您的 python 正在使用的 tk 的底层版本,它可能使用对 <<> 的绑定,而不是直接在 Tab 键上.在这种情况下,您需要以类似的方式解除虚拟事件 <<NextWindow>> 的绑定:

root.unbind_all("<<>")

如果您想删除跳转到下一个窗口的行为,您可能也想删除前一个窗口的行为.该绑定用于虚拟事件 <<>

root.unbind_all("<>")

<块引用>

空格键在选项卡后触发与该按钮关联的命令(即使您在当前选项卡的不同小部件上手动调用 widget.focus_set() ):我该如何防止这种情况?

这绝对不会发生.空格键只能触发具有焦点的按钮,或者您已明确设置自己的绑定来处理其他小部件中的空格键.

I'm trying to intercept the Tab character press without explicitly binding to it at the root or frame level, as this would increase complexity more than desired. I really don't want to bind a simple handler to every button.

I want to know two things:

  1. How do I intercept/disable the background "Tab" key binding?
  2. The Space Bar triggers the command associated with that button after tabbed (even if you manually call widget.focus_set() on a different widget that the current tabbed one): how do I prevent this?

For some reason, Tkinter processes the Tab key to advance to the next object automatically. I don't want this in my case. I also tried "return 'break'" based on this answer but it doesn't seem to work, or the "_get_key" event handler occurs after the background binding.

class testFocus:
    btns = { }
    string = ''
    NumberCharList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'period', 'comma', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    def __init__(self, root):
        self.top = root
        self.top.bind('<Key>', self._get_key)
        self.frame = tk.Frame(self.top)
        self.frame.pack()

        self.var = tk.StringVar(value='Type: ')
        self.lbl = tk.Label(self.frame, textvariable=self.var)
        self.lbl.pack()

        for i in range(15):
            self.btns[i] = tk.Button(self.frame, text=f'Click {i}', command=lambda x=i: print(x))
            self.btns[i].pack()

    def _get_key(self, event):
        print('Root._get_key.event.keysym: ', event.keysym)
        print(root.focus_get())
        if event.keysym in self.NumberCharList:
            self.string += event.keysym
            self.var.set(self.string)
        elif event.keysym == 'Tab':
            print('TAB!') # NOT WORKING...WHY?
        elif event.keysym == 'Delete':
            self.string = ''
            self.var.set(self.string)
        elif event.keysym == 'BackSpace':
            self.string = self.string[:-1]
            self.var.set(self.string)
        # ... other code that handles specific key presses.
        print(root.focus_get())


if __name__ == '__main__':

    root = tk.Tk()
    root.geometry(f"800x480+{int(root.winfo_screenwidth() / 8)}+{int(root.winfo_screenheight() / 6)}")
    root.attributes('-fullscreen', False)
    root.title('Tests')
    root.resizable(width=False, height=False)
    app = testFocus(root)
    root.mainloop()

Tab Output:

Root._get_key.event.keysym:  Tab
.
.
Root._get_key.event.keysym:  Tab
.!frame.!button
.!frame.!button
Root._get_key.event.keysym:  Tab
.!frame.!button2
.!frame.!button2
Root._get_key.event.keysym:  Tab
.!frame.!button3
.!frame.!button3
Root._get_key.event.keysym:  Tab
.!frame.!button7
.!frame.!button7
Root._get_key.event.keysym:  Tab
.!frame.!button8
.!frame.!button8
Root._get_key.event.keysym:  Tab
.!frame.!button9
.!frame.!button9
Root._get_key.event.keysym:  Tab
.!frame.!button10
.!frame.!button10
Root._get_key.event.keysym:  Tab
.!frame.!button12
.!frame.!button12

解决方案

How do I intercept/disable the background "Tab" key binding?

The default tab behavior is based on a binding to the "all" binding tag. You can remove that binding to remove the default tab behavior.

root.unbind_all("<Tab>")

Depending on the underlying version of tk your python is using, it might be using a binding to <<NextWindow>> rather than directly on the tab key. In that case you need to unbind the virtual event <<NextWindow>> in a similar way:

root.unbind_all("<<NextWindow>>")

If you're wanting to remove the behavior tabbing to the next window, you're probably going to want to remove it for the previous window too. That binding is for the virtual event <<PrevWindow>>

root.unbind_all("<<PrevWindow>>")

The Space Bar triggers the command associated with that button after tabbed (even if you manually call widget.focus_set() on a different widget that the current tabbed one): how do I prevent this?

That absolutely will not happen. The space key can only trigger a button if it has focus, or you've explicitly set your own binding to handle the space key in other widgets.

这篇关于使用 Python 3.7.3,如何禁用 Tkinter 的背景“Tab"?键绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆