Tkinter 按钮通过单击鼠标具有打开和关闭功能

Tkinter Button to have on and off function with single mouse click

我正在 tkinter 中构建一个应用程序,我正在使用我在 illustrator 中创建的自定义按钮。我希望我的按钮表现如下: 1. 按钮在 'off' 位置, 2. 鼠标进入按钮屏幕 space 并被点击。 3. 按钮点亮 0.1 秒,然后再次关闭。为了实现这一点,我使用了 'off' 按钮图像。当在按钮图像上单击鼠标左键时,程序会将按钮的图像更改为 'on' 图像。然后过了一段时间,比如 0.1 秒,图像切换回 'off' 位置。为了提供一点上下文,有问题的按钮就像一个带有向上和向下箭头的选择器,按下箭头将显示相关箭头亮起,一些当前选择将更改为下一个可用选择。

我在执行此操作时遇到问题,无论我如何组织我的代码,放置 'off image'、'on image'、'off image' 始终显示关闭图像。

下面的代码是我的代码的简洁版本。我想指出,我知道目前代码的编写方式会导致关闭图像显示,因为我立即将其重新分配给 'off' 图像 :) 这只是为了显示例如。

from tkinter import *
from PIL import ImageTk, Image


# TKINTER WINDOW
root = Tk()
root.title("example")
w=1200
h=800
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))


off_image = ImageTk.PhotoImage(Image.open("example_img1.png"))
on_image = ImageTk.PhotoImage(Image.open("example_img2.png"))

on_off_image_list = [off_image, on_image]

on_off_button = Label(image=on_off_image_list[0])


def on_off_func(event):


    on_off_button = Label(image=on_off_image_list[1])
    on_off_button.bind("<Button-1>", on_off_func)
    on_off_button.place(x=100, y=100)


    # NEED SOME CODE HERE THAT ENABLES THE ABOVE (ON IMAGE ) TO BE SHOWN 
    # THEN SHOW THE ORIGINAL (OFF IMAGE) AGAIN


    on_off_button = Label(image=on_off_image_list[0])
    on_off_button.bind("<Button-1>", on_off_func)
    on_off_button.place(x=100, y=100)



on_off_button.bind("<Button-1>", on_off_func)
on_off_button.place(x=100, y=100)


root.mainloop()

首先:您需要使用config方法配置现有的Label,而不是创建一个新的Label来覆盖旧的Label。第二:您需要使用after 方法来安排在0.1 秒(100 毫秒)内重置。像这样:

from tkinter import *
from PIL import ImageTk, Image

# TKINTER WINDOW
root = Tk()
root.title("example")
root.geometry('200x200')

off_image = ImageTk.PhotoImage(Image.open("example_img1.png"))
on_image = ImageTk.PhotoImage(Image.open("example_img2.png"))

def reset(event=None):
    on_off_button.config(image=off_image)

def on_click(event=None):
    on_off_button.config(image=on_image)
    on_off_button.after(100, reset) # run the reset in 100 milliseconds

on_off_button = Label(image=off_image)
on_off_button.bind("<Button-1>", on_click)
on_off_button.pack()

root.mainloop()

然而,这确实是制作小型自定义小部件的理想场所。您自己的按钮类型。如果你想跳进深渊,你可以这样做:

import tkinter as tk # PEP8 compliant import style
from PIL import ImageTk, Image
from functools import lru_cache

@lru_cache(None)
def load_img(filename):
    """fast loading of repeated images"""
    return ImageTk.PhotoImage(Image.open(filename))

class CustomButton(tk.Label):
    def __init__(self, master=None, command=None, **kwargs):
        self.command = command
        self.off_image = load_img("example_img1.png")
        self.on_image = load_img("example_img2.png")
        super().__init__(master, image=self.off_image, **kwargs)
        self.bind("<Button-1>", self.on_click)

    def reset(self, event=None):
        self.config(image=self.off_image)

    def on_click(self, event=None):
        self.config(image=self.on_image)
        if self.command: self.command()
        self.after(100, self.reset) # run the reset in 100 milliseconds

# EXAMPLE USE TKINTER WINDOW
root = tk.Tk()
root.title("example")
root.geometry('200x200')

button1 = CustomButton(root)
button1.pack()
button2 = CustomButton(root)
button2.pack()
button3 = CustomButton(root)
button3.pack()

root.mainloop()