【问题标题】:Tkinter binding to label not workingTkinter 绑定到标签不起作用
【发布时间】:2018-04-07 14:58:10
【问题描述】:

我目前正在尝试使用 tkinter 中的标签制作按钮。这些按钮具有“Enter”、“Leave”和“Button-1”绑定。当用户将鼠标悬停在标签上时,图像会发生变化,并在他离开标签时恢复正常。当他单击时,事件标签会更改其图像并将其他标签的图像设置为“正常”,但不知何故它不起作用。单击标签后,如果我单击另一个标签并将鼠标悬停在第一个标签上,则图像会按预期通过“输入”绑定更改一次,但不会在“离开”时更改。我将 Python 3.6 与 tkinter 和 PIL 一起用于图像。

这是相关的功能:

def changeBtnPic(buttons, pics, pics_hover, width, height, event) :
    for i in range (0, len(buttons)) : 
        clicked_frame = event.widget
        if clicked_frame == buttons[i] : 
            changeImage(pics_hover[i], buttons[i], width, height)
            buttons[i].unbind('<Leave>')
        elif clicked_frame != buttons[i] :
            changeImage(pics[i], buttons[i], width, height)
            buttons[i].bind('<Leave>', changeImage(pics[i], buttons[i], width, height))

这是它调用的changeImage函数:

def changeImage(img_loc, container, width, height) :
    img = PIL.Image.open(img_loc)
    img = img.resize((width, height), PIL.Image.ANTIALIAS)
    img = PIL.ImageTk.PhotoImage(img)

    container.config(image = img)
    container.image = img

这里是标签的创建和绑定:

lbtn_npcs    = generateImage(dir + '/resources/images/buttons/npcs.png', 204, 100, fr_top,  bg = '#252A29', x = '1054', y = '0', cur = 'hand2')
lbtn_enemies = generateImage(dir + '/resources/images/buttons/enemies.png', 204, 100, fr_top,  bg = '#252A29', x = '830', y = '0', cur = 'hand2')
lbtn_players = generateImage(dir + '/resources/images/buttons/players.png', 204, 100, fr_top,  bg = '#252A29', x = '606', y = '0', cur = 'hand2')

buttons_top = [lbtn_npcs, lbtn_enemies, lbtn_players]
pics        = [dir + "/resources/images/buttons/npcs.png", dir + "/resources/images/buttons/enemies.png", dir + "/resources/images/buttons/players.png"]
pics_hover  = [dir + "/resources/images/buttons/npcs_hover.png", dir + "/resources/images/buttons/enemies_hover.png", dir + "/resources/images/buttons/players_hover.png"].

lbtn_npcs.bind("<Enter>", lambda event : changeImage(dir + "/resources/images/buttons/npcs_hover.png", lbtn_npcs, 204, 100))
lbtn_npcs.bind("<Leave>", lambda event : changeImage(dir + "/resources/images/buttons/npcs.png", lbtn_npcs, 204, 100))
lbtn_npcs.bind("<Button-1>", lambda event : changeBtnPic(buttons_top, pics, pics_hover, 204, 100, event))

lbtn_enemies.bind("<Enter>", lambda event : changeImage(dir + "/resources/images/buttons/enemies_hover.png", lbtn_enemies, 204, 100))
lbtn_enemies.bind("<Leave>", lambda event : changeImage(dir + "/resources/images/buttons/enemies.png", lbtn_enemies, 204, 100))
lbtn_enemies.bind("<Button-1>", lambda event : changeBtnPic(buttons_top, pics, pics_hover, 204, 100, event))

lbtn_players.bind("<Enter>", lambda event : changeImage(dir + "/resources/images/buttons/players_hover.png", lbtn_players, 204, 100))
lbtn_players.bind("<Leave>", lambda event : changeImage(dir + "/resources/images/buttons/players.png", lbtn_players, 204, 100))
lbtn_players.bind("<Button-1>", lambda event : changeBtnPic(buttons_top, pics, pics_hover, 204, 100, event))

def generateImage(img_loc, width, height, container, **kwargs) :

    bg = kwargs.get('bg')
    x  = kwargs.get('x')
    y  = kwargs.get('y')

    img = PIL.Image.open(img_loc)
    img = img.resize((width, height), PIL.Image.ANTIALIAS)
    img = PIL.ImageTk.PhotoImage(img)

    lb_img = tk.Label(container, image = img, bg = "#252A29")
    if bg :
        lb_img.config(bg = bg)
    lb_img.image = img
    lb_img.pack()

    if x and y :
        lb_img.place(x = int(x), y = int(y))
    return(lb_img)

我想重新绑定不起作用,但我不知道这是否真的是原因,也不知道如何解决它。你有什么想法或线索吗?

谢谢!

【问题讨论】:

  • 您不能发布您的代码图片,我们需要您复制并粘贴实际代码:)
  • @Coal_ 完成。抱歉,我没有看到这个选项^^
  • 您的缩进也有一点问题,请修复第一个代码块。请至少提供一个完整的例子。 lbtn_npcslbtn_enemieslbtn_players 的代码在哪里?如果可以,请在此处粘贴所有内容。
  • @Coal_ 再次完成,对错误深表歉意!

标签: python tkinter python-3.6 pillow


【解决方案1】:

不要使用 lambda,而是尝试使用 partial。在代码顶部包含from functools import partial,并替换所有调用,如

lambda event : changeImage(dir + "/resources/images/buttons/players_hover.png", lbtn_players, 204, 100)

partial(change_image, dir + "/resources/images/buttons/players_hover.png", lbtn_players, 204, 100)

下面的链接应该向您解释为什么这样做(假设我已正确识别问题)。 How does the functools partial work in Python?

【讨论】:

  • 它没有用。它引发了一个 TypeError,告诉我该函数接受 4 个参数但给出了 5 个参数,如果我正确理解了部分函数,​​这是正常的。但是我不明白第五个论点可能是什么。还是谢谢这个功能,没听说过,可能会再深入研究一下!
  • 我认为 bind 在通过部分调用 change_image 时可能会尝试传递一个事件对象,这就是它说 5 个参数的原因。尝试添加一个额外的参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多