【问题标题】:how to use Tcl/Tk bind function on Tkinter's widgets in Python?如何在 Python 中的 Tkinter 的小部件上使用 Tcl/Tk 绑定函数?
【发布时间】:2017-01-28 16:19:27
【问题描述】:

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

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

【问题讨论】:

  • 当你说“我如何使用这个功能”时,“这个功能”是什么意思?你指的是eval吗?你问如何在绑定中使用%d
  • 我的意思是“如何在绑定中使用 %d”

标签: python tkinter tcl bind tk


【解决方案1】:

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

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

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

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

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()

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

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

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

那么,第一步就是注册回调。我们已经创建了函数,我们只需要创建一个调用这个函数的 tcl 函数。幸运的是,tkinter 为我们提供了一种使用 register 命令的方法。你可以这样使用它:

cmd = root.register(callback)

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

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

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

python 等价物是这样的:

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

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

把它们放在一起给我们这个,当你点击按钮时,它会打印出“detail: Hello, world”:

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()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 2022-12-14
  • 1970-01-01
相关资源
最近更新 更多