Tkinter绑定事件传递给函数而不是变量

时间:2019-06-07 11:34:40

标签: python tkinter

我正在尝试为应用程序创建一个简单的颜色选择器。我正在生成具有不同背景颜色的标签数组。单击标签后,我想将十六进制颜色放入父窗口小部件的输入字段中。

一切正常加载,但是似乎我将bind事件实例传递给了set_color方法,而不是十六进制颜色。我在做什么错了?

我可以在命令中使用按钮,但是这些按钮需要更长的加载时间。

# Python 2.7
import Tkinter as tk
from tkFont import Font
import math

class ColorPicker(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        self.parent = parent
        self.title("ColorPicker")

        self.frame = tk.Frame(self)
        self.frame.pack()

        self.buttonfont = Font(family="Arial", size=5)

        ROW, COL = 0, 0
        COLORS = xrange(1, int("FFFFFF", base=16), 50000)
        for color in COLORS:
            hexcolor = "#" + str(hex(color))[2:]
            hexcolor += "0"*(7 - len(hexcolor))

            l = tk.Label(self.frame, bg=hexcolor, text=hexcolor, font=self.buttonfont)
            l.bind("<Button-1>", lambda x=hexcolor: self.set_color(x))
            l.grid(row=ROW, column=COL)

            ROW += 1
            if ROW > math.sqrt(len(COLORS)):
                ROW = 0
                COL += 1

    def set_color(self, color):
        self.parent.entry_background_color.delete(0, tk.END)
        self.parent.entry_background_color.insert(0, color)
        self.destroy()

这是一个运行并复制行为的小示例。

import Tkinter as tk

def p(s, *args):
    print(s)

app = tk.Tk()
frame = tk.Frame(app)
frame.pack()

for i in range(3):
    label = tk.Label(app, text="Press Me")
    label.pack()
    label.bind("<Button-1>", lambda i=i: p("Hello World {} times".format(i)))

app.mainloop()

1 个答案:

答案 0 :(得分:1)

绑定正在生成一个必须在lambda中消耗的事件:

l.bind("<Button-1>", lambda event, x=hexcolor: self.set_color(x))
#                             ^         ^
#         consume event-------|         | and then assign x

否则,lambda会将事件分配给hexcolor

更新

关于标签无法响应的问题,我无法重现。但是,我确实考虑了一下,并想出了一种分配ROW和COL的方法,感觉更像Python了:

import Tkinter as tk
import math

class ColorPicker(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        self.parent = parent
        self.title("ColorPicker")

        self.frame = tk.Frame(self)
        self.frame.pack()

        ROW, COL = 0, 0
        COLORS = xrange(1, int("FFFFFF", base=16), 50000)
        for count, color in enumerate(COLORS):
            hexcolor = "#" + str(hex(color))[2:]
            hexcolor += "0"*(7 - len(hexcolor))

            ROW = count // int(math.sqrt(len(COLORS)))
            COL = count % int(math.sqrt(len(COLORS)))

            l = tk.Label(self.frame, bg=hexcolor, text=hexcolor)
            l.bind("<Button-1>", lambda event, x=hexcolor: self.set_color(x))
            l.grid(row=ROW, column=COL)

    def set_color(self, color):
        print color

root = tk.Tk()
app = ColorPicker(root)

请注意,我运行的是Python 3.6.5,可能会有一些差异。