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()
我正在 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()