如何在 Python 中的 Tkinter 小部件上使用 Tcl/Tk 绑定函数? [英] how to use Tcl/Tk bind function on Tkinter's widgets in Python?

查看:30
本文介绍了如何在 Python 中的 Tkinter 小部件上使用 Tcl/Tk 绑定函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然 Tkinter 是从 Tcl/Tk 派生的,但它不如 Tcl/Tk 完整.Tcl/Tk 绑定函数有一些 tkinter 没有的属性(例如 %d 返回事件的详细信息字段 https://www.tcl.tk/man/tcl8.4/TkCmd/bind.htm#M24).
Python 中的eval"函数可以使用 Tcl/Tk 脚本,但我不知道如何在 Tcl/Tk 脚本中声明 tkinter 小部件.

那么我如何在 Tkinter 小部件上使用此函数及其属性?

解决方案

如果您正在询问如何创建使用数据"字段的绑定(即:%d 替换),你将不得不调用一些 tcl 代码来实现这一点.这需要两个步骤:创建一个调用python函数的tcl命令,并使用tcl将事件绑定到该函数.

首先,让我们创建一个可以创建事件并设置数据"字段的python程序(假设存在一个名为root的全局变量,我们稍后会创建).调用此函数时,它将生成一个自定义事件,其中数据字段由字符串填充.

def create_custom_event():root.event_generate("<<Custom>>", data="Hello, world")

接下来,让我们创建一个程序,在按下按钮时调用该函数

将 tkinter 导入为 tk根 = tk.Tk()button = tk.Button(root, text="click me", command=create_custom_event)button.pack(side="top", padx=20, pady=20)root.mainloop()

接下来我们需要创建一个在事件产生时调用的函数.我们计划设置data 字段,因此该函数必须接受一个值,即%d 替换的值.

def 回调(详细信息):打印(详细信息:%s"% 详细信息)

因为您想使用 %d 替换,我们必须通过 Tcl 创建绑定.但是,tcl 不会自动知道我们的 Python 函数,因此我们必须向 tcl 注册该函数.那么只需通过tcl接口调用bind来设置绑定即可.

然后,第一步是注册回调.我们已经创建了这个函数,我们只需要创建一个调用这个函数的 tcl 函数.幸运的是,tkinter 为我们提供了一种使用 register 命令来做到这一点的方法.你像这样使用它:

cmd = root.register(回调)

这需要一个 python 函数(在本例中为 callback),并创建一个将调用该函数的 tcl 命令.register 返回我们存储在名为 cmd 的变量中的那个 tcl 命令的名称(名称无关紧要)

接下来,我们需要通过Tcl设置一个绑定来调用这个命令.如果我们在实际的 tcl 脚本中执行此操作,该命令将如下所示(其中."代表根窗口):

绑定.<<自定义>>{回调%d}

python 等价物是这样的:

root.tk.call("bind", root, "<<自定义>>", cmd + " %d")

请注意,call 的参数和 tcl 参数之间存在 1:1 的对应关系.方便的是,tkinter 小部件的默认字符串表示是内部 tcl 名称,因此我们可以直接在调用中使用小部件(尽管,迂腐,也许我们应该使用 str(root)).

把它们放在一起给我们这个,当你点击按钮时,它会打印出细节:你好,世界":

将 tkinter 导入为 tk定义回调(详细信息):打印(详细信息:%s"% 详细信息)def create_custom_event():root.event_generate("<<Custom>>", data="Hello, world")根 = tk.Tk()button = tk.Button(root, text="click me", command=create_custom_event)button.pack(side="top", padx=20, pady=20)cmd = root.register(回调)root.tk.call("bind", root, "<<自定义>>", cmd + " %d")root.mainloop()

Although Tkinter's derived from Tcl/Tk but it's not as complete as Tcl/Tk. Tcl/Tk bind function has some attributes which tkinter doesn't (e.g. %d that returns The detail field from the event https://www.tcl.tk/man/tcl8.4/TkCmd/bind.htm#M24).
Tcl/Tk scripts can be used by "eval" function in python but i don't know how to declare a tkinter widget in Tcl/Tk script.

so how can i use this function and its attributes on Tkinter widget?

解决方案

If you are asking how to create a binding that makes use of the "data" field (ie: %d substitution), you will have to call some tcl code to make that happen. This requires two steps: create a tcl command that calls a python function, and use tcl to bind an event to that function.

First, let's create a python program that can create an event and set the "data" field (this assumes the existence of a global variable named root, which we'll create later). When this function is called, it will generate a custom event with the data field populated by a string.

def create_custom_event():
    root.event_generate("<<Custom>>", data="Hello, world")

Next, lets create a program to call that function on a button press

import tkinter as tk
root = tk.Tk()
button = tk.Button(root, text="click me", command=create_custom_event)
button.pack(side="top", padx=20, pady=20)
root.mainloop()

Next we need to create a function that is called when the event is generated. We plan to set the data field, so this function must accept one value which is the value of the %d substitution.

def callback(detail):
    print("detail: %s" % detail)

Because you want to use the %d substitution we'll have to create the binding via Tcl. However, tcl doesn't automatically know about our python functions so we have to register the function with tcl. Then it's just a matter of calling bind via the tcl interface to set up the binding.

The first step, then, is to register the callback. We've already created the function, we just have to create a tcl function that calls this function. Fortunately, tkinter gives us a way to do that with the register command. You use it like this:

cmd = root.register(callback)

This takes a python function (callback in this case), and creates a tcl command which will call that function. register returns the name of that tcl command which we store in a variable named cmd (the name is irrelevant)

Next, we need to set up a binding via Tcl to call this command. If we were doing this in an actual tcl script, the command would look something like this (where "." represents the root window):

bind . <<Custom>> {callback %d}

The python equivalent is this:

root.tk.call("bind", root, "<<Custom>>", cmd + " %d")

Notice that there is a 1:1 correspondence between an argument to call and a tcl argument. Conveniently, the default string representation of a tkinter widget is the internal tcl name, so we can directly use the widget in the call (though, pedantically, perhaps we should use str(root)).

Putting it all together gives us this, which prints out "detail: Hello, world" when you click the button:

import tkinter as tk

def callback(detail):
    print("detail: %s" % detail)

def create_custom_event():
    root.event_generate("<<Custom>>", data="Hello, world")

root = tk.Tk()

button = tk.Button(root, text="click me", command=create_custom_event)
button.pack(side="top", padx=20, pady=20)

cmd = root.register(callback)
root.tk.call("bind", root, "<<Custom>>", cmd + " %d")

root.mainloop()

这篇关于如何在 Python 中的 Tkinter 小部件上使用 Tcl/Tk 绑定函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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