我有一个PYTHON图形用户界面和Tkinter.在一堂课上,我有一些文本小工具.它们有大约default bindings个,我想最好用bind_class()个来取代其中的一些.除了那些热键大写的,比如Ctrl-E/A/B/F(即Ctrl-Shift-e/a/b/f),我所有的都做到了.我只能通过在每个小部件上分别应用bind()方法来更改这些.我想知道为什么会这样,是否有更聪明的方法来处理bind_class(),否则它似乎不会对上面提到的默认绑定产生任何影响.

请考虑下面的代码.在点击每个文本窗口小部件并try 所有四个热键(Ctrl-b/B/y/Y)后,可以看到它们在两个窗口小部件中都能像预期的那样工作,除了Ctrl-B(即Ctrl-Shift-b),只有当它与带有bind()的窗口小部件绑定时才能工作.

就像我现在看到的这个问题:对于一个带有大写键的内置函数,优先级显然是这样的:bind()>结尾可能是return 'break'的内置函数.这意味着,bind_class()永远不会工作,只有在bind()中引用的函数末尾没有return 'break'的情况下,才会调用内置函数.同时,带有小写字母键的内置热键(例如Ctrl-a/e/b/f)的优先级较低,甚至bind_class()也可以优先于它们.

所以我的问题是:

  1. 我的上述结论是正确的,还是有其他原因?
  2. 这是bind()bind_class()的预期功能吗?
  3. 在某种程度上,是否仍然有可能覆盖像Ctrl-B这样的内置函数,一次只对所有小部件使用bind_class(),而不是逐个使用bind()

欢迎任何有见地的 comments .谢谢!

from tkinter import *

class Test:
    def __init__(self):
        self.window = Toplevel(root)
        self.window.lift()
        
        self.t1 = Text(self.window)
        self.t1.insert(1.0, 'Initial text in Text widget #1')
        #self.t1.bind('<Control-B>', self.func)
        self.t1.pack()
        
        self.t2 = Text(self.window)
        self.t2.insert(1.0, 'Initial text in Text widget #2')
        self.t2.bind('<Control-B>', self.func)
        self.t2.pack()
        
        self.t1.bind_class('Text', '<Control-b>', self.func)
        self.t1.bind_class('Text', '<Control-B>', self.func)   # This line has no effect.
        
        self.t1.bind_class('Text', '<Control-y>', self.func)
        self.t1.bind_class('Text', '<Control-Y>', self.func)
    
    def func(self, event):
        obj = root.focus_get()
        obj.insert(END, '\n'+str(event))
        return 'break'

root = Tk()
t1 = Test()
root.lower()
root.mainloop()

推荐答案

优先级顺序不变,在所有情况下对所有小部件都是相同的,并且总是由小部件的绑定标签定义.所以,回答你最初的几个问题:不,你的结论是不正确的,是的,这是按设计工作的.

这种情况下的问题是,至少在某些平台上,<Control-Shift-Key-B>与虚拟事件<<SelectPrevChar>>相关联(并且<Control-B><Control-Shift-Key-B>相同).当您按下Ctrl+B时,事件在传递给小部件之前被转换为<<SelectPrevChar>>虚拟事件.类绑定位于该事件上,而不是原始按键上.换句话说,这个小部件永远不会看到<Control-Shift-Key-B>个,它只看到<<SelectPrevChar>>个.

您可以通过以下两种方法之一来解决此问题:

  • 您可以移除虚拟事件,在这种情况下,类绑定将起作用
  • 您可以更改虚拟事件的类绑定

要从虚拟事件中删除该特定原始事件并将显式绑定添加到原始事件序列,可以执行以下操作:

self.window.event_delete("<<SelectPrevChar>>", "<Control-Shift-Key-B>")
self.t1.bind_class("Text", "<Control-Shift-Key-B>", self.func)

要更改虚拟事件的类绑定,可以在虚拟事件上使用bind_class:

self.t1.bind_class("Text", "<<SelectPrevChar>>", self.func)

要查看所有虚拟事件及其绑定的键的列表,可以运行这段代码,该代码使用不带参数的event_info命令来获取虚拟事件的列表,然后使用相同的方法来获取有关每个事件的信息.

for event in self.window.event_info():
    info = self.window.event_info(event)
    print(f"{event:<20s} => {', '.join(info)}")

Python相关问答推荐

X射线扫描显示Docker中的pip漏洞,尽管图像中未安装pip

预期LP_c_Short实例而不是_ctyles.PyCStructType

使用decorator 自动继承父类

获取Azure Pipelines以从pyproject.toml(而不是relevments_dev.文本)安装测试环境

如何在不使用字符串的情况下将namedtuple属性传递给方法?

PyQt5如何将pyuic 5生成的Python类添加到QStackedWidget中?

pyautogui.locateOnScreen在Linux上的工作方式有所不同

线性模型PanelOLS和statmodels OLS之间的区别

使用SciPy进行曲线匹配未能给出正确的匹配

TARete错误:类型对象任务没有属性模型'

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

如何从具有不同len的列表字典中创建摘要表?

如何在虚拟Python环境中运行Python程序?

在Python中动态计算范围

优化器的运行顺序影响PyTorch中的预测

我想一列Panadas的Rashrame,这是一个URL,我保存为CSV,可以直接点击

在含噪声的3D点网格中识别4连通点模式

计算天数

用渐近模计算含符号的矩阵乘法

使用Python查找、替换和调整PDF中的图像'