多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Linking Events to Callback Functions 我不会尝试完全解释Tk和Tkinter的事件绑定。 我已经读过几本书和许多有关该主题的网页,但感觉不太熟练。 将事件绑定到小部件是使用Tk和Tkinter的一个非常令人困惑的方面。 Tk实现了全局绑定层次结构,因为Tk允许在操作之间创建绑定,并且 1. 特定小部件内的事件,例如鼠标选择和特定按钮, 2. 特定类别的小部件内的事件,例如鼠标选择和应用程序中的所有按钮, 3. 顶层窗口中所有窗口小部件中的事件,以及 4. 应用程序中所有小部件内的事件。 PAGE实际上仅辅助第一种绑定。 至少一位受人尊敬的文档撰写者建议不要使用其他三篇。 如果您觉得有必要对绑定进行分类,则可以将其手动添加到支持模块中的“ init”功能中。 Grayson在他的书中谈到了直接或间接调用回调。 指定命令属性将导致间接调用,而指定绑定命令将导致直接调用。 不同之处在于,直接调用将事件对象传递给回调,并且回调函数必须具有包含该事件参数的参数列表。 要查看直接和间接调用回调的示例,请参见vrex示例或bind示例。 人们还可以将它们描述为清晰而混乱,或者简单而复杂。 首先让我讨论一种简单的情况,即指定命令属性。 许多小部件都有一个command属性,该属性指定了用Button-1选择小部件时要执行的代码。 对于使用Button-1选择小部件的常见情况,这是一种简化的绑定方式。 虽然Tk允许指定一个代码块,但必须坚持使用Python中的函数调用。 例如,将按钮的命令属性设置为“ foo”,以便选择Button-1将导致不带参数的函数“ foo”的调用。 如果要调用一个函数并将参数传递给它,则可以使用lambda表达式。 请参阅Grayson的书第6.4节,详细了解在这种情况下使用lambda表达式。 (简而言之,如果Python遇到后跟括号的函数名称,它将尝试立即执行该函数,而在事件发生时则需要执行。)假设您要调用函数foo并将其3传递给 一个参数,您作为命令输入的是 ~~~ lambda : foo(3) ~~~ 不是 ~~~ foo(3) ~~~ 或传递可变参数 ~~~ lambda x: foo(x) ~~~ 不是 ~~~ foo(x) ~~~ 要指定这样的命令,请选择一个小部件,然后在“属性编辑器”中的“命令”字段中输入该命令。 为了保持具有完成大多数事情的太多方式的Virtual Tcl风格,一种替代方法是使用Button-3在Widget Tree中选择Widget,然后选择Widget-> Set Command。 我不经常使用替代方法。 除了这一段之外,我可能会忘记它。 当指定Entry小部件或Tk_entry小部件的“ validatecommand”和“ invalidcommand”选项时,命令字符串必须是一个元组,第一个元素是命令名称,其他元素限于: * %d = 动作类型(1 =插入,0 =删除,其他为-1) * %i =要插入/删除的char字符串的索引,或-1 * %P = 条目的值(如果允许编辑) * %s = 编辑前的输入值 * %S = 插入或删除的文本字符串(如果有) * %v =当前设置的验证类型 * %V = 触发回调的验证类型 (key, focusin, focusout, forced) * %W = 小部件的tk名称 每个元素都用引号引起来。 例如: ~~~ (vcmd, '%P', '%S', '%W') ~~~ 因此,将发生的情况是,PAGE函数将在支持模块中由PAGE创建一个骨架函数vcmd,其中可变数量的参数以entry的值作为第一个参数,插入的字符串作为第二个参数,而widget信息作为第三个参数。 请注意,%W不会传递小部件,而是将小部件转换为字符串。 我认为这是tkinter中的错误。 在tkinter中,它的行为肯定不同于在Tcl / Tk中的行为。 骨架函数如下所示: ~~~ def vcmd(*args): print('v2_support.vcmd') for arg in args: print ('another arg:', arg) sys.stdout.flush() return True ~~~ 请注意,验证函数必须返回True或False。 简单案例的绑定就这么多了,该案例本质上定义了一个配置命令,用于在生成的Python中设置小部件的command属性。为了将其他事件绑定到窗口小部件,我将指向构建窗口的Bindings窗口。当然,可以在支持模块的init功能中手动编码bind命令。 对于许多小部件而言,command属性是必经之路,并且很容易将视为关联的事件。实际上,是关联的事件。差异可能很重要。例如,“复选框”窗口小部件将关联变量设置为新值,作为事件的最后一步。 另一个建议是,虽然command属性通常会传递零个参数或lambda函数中指定的参数。对于Scale和TScale小部件,将scale的最终值作为第一个参数传递给回调函数。看到[Scale and TScale](use.md)￿￿⭸Ɵ耀I⭸Ɵ耀⭸Ɵ耀02⭸Ɵ耀Iዀ戻翽uem'd翽 闠㩏Ɵ鈈㩏Ɵ醀㩏Ɵ娈戾翽ĀŨ㬀㢾Ɵ㲰戹翽ዀ戻翽 詨㩏Ɵ搘㩏Ɵ諰㩏Ɵ૽Ɵ⭸Ɵ耀⭸Ɵ⭸Ɵ灐ჀƟ 镘㩏Ɵ晈㩏Ɵ铐㩏Ɵ⭸Ɵ�⭸Ɵ ૜Ɵ૽Ɵ⭸Ɵ耀灐ჀƟ￿￿翽環ჀƟ￿￿㲰戹翽ƟƟ挈㩏Ɵmo⭸Ɵ耀巸ଯƟmo⭸Ɵ耀ᘐmo⭸Ɵ耀Ɵmo⭸Ɵ耀￿mousemove⭸Ɵ耀Ɵmo⭸Ɵ耀md).