Python Tkinter按钮具有打开和关闭功能,只需单击鼠标

Python Tkinter按钮具有打开和关闭功能,只需单击鼠标,python,tkinter,button,mouseevent,Python,Tkinter,Button,Mouseevent,我正在tkinter中构建一个应用程序,我正在使用illustrator中创建的自定义按钮。我希望我的按钮的行为如下:1。按钮处于“关闭”位置,2。鼠标进入按钮屏幕空间并被单击。3.按钮打开0.1秒,然后再次关闭。为了实现这一点,我使用了按钮的“关闭”图像。当鼠标左键单击按钮图像时,程序会将按钮图像更改为“打开”图像。然后,经过一段时间(比如0.1秒),图像切换回“关闭”位置。要提供一点上下文信息,该按钮就像一个带有上下箭头的选择器,按下箭头将显示相关箭头亮起,并且一些当前选择将更改为下一个可用

我正在tkinter中构建一个应用程序,我正在使用illustrator中创建的自定义按钮。我希望我的按钮的行为如下:1。按钮处于“关闭”位置,2。鼠标进入按钮屏幕空间并被单击。3.按钮打开0.1秒,然后再次关闭。为了实现这一点,我使用了按钮的“关闭”图像。当鼠标左键单击按钮图像时,程序会将按钮图像更改为“打开”图像。然后,经过一段时间(比如0.1秒),图像切换回“关闭”位置。要提供一点上下文信息,该按钮就像一个带有上下箭头的选择器,按下箭头将显示相关箭头亮起,并且一些当前选择将更改为下一个可用选择

我很难做到这一点,无论我如何组织我的代码,推迟“关闭图像”,“打开图像”,“关闭图像”只是显示关闭的图像所有的时间

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

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()
从tkinter导入*
从PIL导入ImageTk,图像
#特金特窗
root=Tk()
root.title(“示例”)
w=1200
h=800
ws=root.winfo_屏幕宽度()
hs=root.winfo_屏幕高度()
x=(w/2)-(w/2)
y=(hs/2)-(h/2)
几何体(“%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]
开/关按钮=标签(图像=开/关图像列表[0])
def开/关功能(事件):
开/关按钮=标签(图像=开/关图像列表[1])
开/关按钮。绑定(“,开/关功能)
开关按钮。放置(x=100,y=100)
#需要一些代码在这里,使上述(在图片上)可以显示
#然后再次显示原始(关闭图像)
开/关按钮=标签(图像=开/关图像列表[0])
开/关按钮。绑定(“,开/关功能)
开关按钮。放置(x=100,y=100)
开/关按钮。绑定(“,开/关功能)
开关按钮。放置(x=100,y=100)
root.mainloop()

首先:您需要使用
config
方法配置现有标签,而不是制作新标签来覆盖旧标签。第二:您需要使用
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()
从tkinter导入*
从PIL导入ImageTk,图像
#特金特窗
root=Tk()
root.title(“示例”)
root.geometry('200x200')
off_image=ImageTk.PhotoImage(image.open(“example_img1.png”))
on_image=ImageTk.PhotoImage(image.open(“example_img2.png”))
def重置(事件=无):
on\u off\u button.config(image=off\u image)
单击时的def(事件=无):
on\u off\u button.config(image=on\u image)
on_off_按钮。在(100,重置)后#在100毫秒内运行重置
打开\关闭\按钮=标签(图像=关闭\图像)
打开/关闭按钮。绑定(“,单击时)
打开/关闭按钮。打包()
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()
将tkinter作为tk#PEP8兼容的导入样式导入
从PIL导入ImageTk,图像
从functools导入lru\U缓存
@lru_缓存(无)
def load_img(文件名):
“”“快速加载重复图像”“”
返回ImageTk.PhotoImage(Image.open(文件名))
类自定义按钮(tk.标签):
定义初始化(self,master=None,command=None,**kwargs):
self.command=命令
self.off\u image=load\u img(“example\u img1.png”)
self.on_image=load_img(“example_img2.png”)
超级()
self.bind(“,self.on_单击)
def重置(自身,事件=无):
self.config(image=self.off\u image)
单击时的def(自身,事件=无):
self.config(image=self.on_image)
如果self.command:self.command()
self.after(100,self.reset)#在100毫秒内运行重置
#使用TKINTER窗口的示例
root=tk.tk()
root.title(“示例”)
root.geometry('200x200')
button1=自定义按钮(根)
按钮1.pack()
button2=自定义按钮(根)
按钮2.pack()
button3=自定义按钮(根)
按钮3.pack()
root.mainloop()

谢谢你的小说,这正是我想要的,我也会看看你的自定义按钮,然后试一试。