【问题标题】:Confused about Tkinter bind_class对 Tkinter bind_class 感到困惑
【发布时间】:2016-11-04 11:51:12
【问题描述】:

我定义了 GCanvas,它是 Canvas 的扩展。我的意图是在班级级别绑定到 GCanvas。它不工作。

我也尝试绑定到 tk.Canvas,但它也不起作用。绑定到root 或 GCanvas 实例可以正常工作。 (这两种选择对我都没有用,但我只是尝试了它们看看发生了什么。)。运行 OS X,El Capitan。

import Tkinter as tk

class GCanvas(tk.Canvas, object):

    def __init__(self, master, **kwargs):
        tk.Canvas.__init__(self, master, kwargs)

    @staticmethod
    def enter(e):
        print "enter", e.widget, e.x, e.y

    @staticmethod
    def leave(e):
        print "leave", e.widget

    @staticmethod
    def motion(e):
        print "motion", e.widget, e.x, e.y

approach = "bindinstance"

root = tk.Tk()
gc = GCanvas(root, width=400, height=300)
print "root is", root, "gc is", gc
gc.pack()

if approach == "bindGCanvas":
    print "binding to GCanvas"
    root.bind_class(GCanvas, '<Enter>', GCanvas.enter)
    root.bind_class(GCanvas, '<Leave>', GCanvas.leave)
    #root.bind_class(GCanvas, '<Motion>', GCanvas.motion)
elif approach == "bindCanvas":
    print "binding to Canvas"
    root.bind_class(tk.Canvas, '<Enter>', GCanvas.enter)
    root.bind_class(tk.Canvas, '<Leave>', GCanvas.leave)
    #root.bind_class(tk.Canvas, '<Motion>', GCanvas.motion)
elif approach == "bindinstance":
    print "binding to instance"
    gc.bind('<Enter>', GCanvas.enter)
    gc.bind('<Leave>', GCanvas.leave)
    #gc.bind('<Motion>', GCanvas.motion)
else:
    print "binding to root"
    root.bind('<Enter>', GCanvas.enter)
    root.bind('<Leave>', GCanvas.leave)
    #root.bind('<Motion>', GCanvas.motion)

root.mainloop()

【问题讨论】:

    标签: python-2.7 tkinter tkinter-canvas


    【解决方案1】:

    bind_class中的“类”指的是tk库使用的内部类名,不是python类名。更准确地说,在这种情况下,它指的是一个 bind 标记,它恰好与 tk 类同名,它也恰好与核心 Tkinter 类之一同名(例如: Toplevel、Canvas 等)。

    要在类级别绑定到GCanvas,最简单的方法是在画布上添加一个名为GCanvas 的绑定标签,如下例所示:

    class GCanvas(tk.Canvas, object):
        def __init__(self, master, **kwargs):
            ...
            # get the current bind tags
            bindtags = list(self.bindtags())
    
            # add our custom bind tag before the Canvas bind tag
            index = bindtags.index("Canvas")
            bindtags.insert(index, "GCanvas")
    
            # save the bind tags back to the widget
            self.bindtags(tuple(bindtags))
    

    然后您可以像这样使用bind_class:

    root.bind_class("GCanvas", "<Enter>", GCanvas.enter)
    root.bind_class("GCanvas", "<Leave>", GCanvas.leave)
    

    有关绑定标签的更多信息,请参阅这些对其他一些 tkinter 问题的回答:

    【讨论】:

    • 谢谢!所以我根本不需要定义 Python 类;我只需要在我的画布上添加一个独特的绑定标签,对吧?
    • @Eduardo:正确。我建议使用一个类来创建一种新类型的画布,但严格来说你不需要。
    • 如果我有一个自定义的Frame 并且在这个框架内,还有其他小部件会怎样。我将如何进行绑定以使绑定在我单击此自定义框架时起作用?
    • @CoolCloud:可以在框架的bindtags中添加GCanvas标签。
    • 我确实添加了这一点,但是当Label 在框架内聚焦时,绑定不再起作用
    【解决方案2】:

    我找到的一个快速解决方案可以解决两个 text() 框之间的绑定冲突。 列出绑定标签以对小部件的路径进行排序。列表中的第一次出现。绑定同时在两个小部件上触发。

    self.frame2 = Frame(self)
    self.frame2.pack()
    self.textDomain = Text(self.frame2, width=21, height=10, wrap=WORD, borderwidth=2, relief=GROOVE)
    self.textDomain.pack()
    self.bindtags = list(self.textDomain.bindtags())
    self.textDomain.bind_class(str(self.bindtags[0]), "<Return>", lambda _: self.verifytextBox("textDomain"))
    self.textDomain.bind_class(str(self.bindtags[0]), "<Leave>", lambda _: self.verifytextBox("textDomain"))
    self.textExtension = Text(self.frame2, width=21, height=10, wrap=WORD, borderwidth=2, relief=GROOVE)
    self.textExtension.pack()
    self.bindtags = list(self.textExtension.bindtags())
    self.textExtension.bind_class(str(self.bindtags[0]), "<Return>", lambda _: self.verifytextBox("textExtension"))
    self.textExtension.bind_class(str(self.bindtags[0]), "<Leave>", lambda _: self.verifytextBox("textExtension"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-13
      • 2012-07-22
      • 2013-05-13
      • 2020-04-16
      • 2023-03-08
      • 2019-08-04
      • 2019-12-30
      相关资源
      最近更新 更多