在关闭 tkinter python 之前 window 平滑淡化

Smooth fading of window before closing tkinter python

我用 tkinter 制作了一个简单的工具提示并添加了淡入淡出效果,但是代码出现问题:

import tkinter as tk
import time

class ToolTips():
    def __init__(self,widget,text,triggerkey='<Enter>',releasekey='<Leave>'):
        self.widget = widget
        self.text = text
        self.bg = '#ffffe0'
        self.widget.bind(triggerkey,self.add)
        self.widget.bind(releasekey,self.remove)
        self.widget.bind('<ButtonPress>',self.remove)
        
    def add(self,event):
        self.master = tk.Toplevel(bg=self.bg)
        self.master.geometry(f'+{event.x_root}+{event.y_root}')
        self.master.overrideredirect(1)
        self.master.attributes('-topmost',True)
        self.frame = tk.Frame(self.master,bg=self.bg,highlightbackground="black", highlightcolor="black", highlightthickness=1)
        self.frame.pack()
        self.label = tk.Label(self.frame,text=self.text,bg=self.bg,justify=tk.LEFT)
        self.label.pack(padx=1,pady=3)
    
    def remove(self,*args):
        alpha = self.master.attributes('-alpha')
        if alpha > 0:
            alpha -= 0.5
            self.master.attributes('-alpha',alpha)
            self.master.after(100,self.remove)
        else:
            self.master.destroy()

#USAGE OF CLASS
root = tk.Tk()

l = tk.Label(root,text='Hover',font=('hevletica',21))
l.pack()
l.focus_force()

obj = ToolTips(l,text='There is alot more to this? Are you curious?\nBla Bla...')

root.mainloop()

这里 remove() 本来应该提供淡入淡出的效果,但它不干净,有时如果你离开标签并进入标签的速度超过 100 毫秒,那么工具提示不会破坏并会留在那儿永远直到应用程序完全退出。那么有没有什么简单的方法,如果没有,有什么方法可以实现此工具提示的平滑淡入淡出。也请随时指出代码中的其他错误:)

答案有淡入淡出的效果,不过我的代码好像实现不了

提前致谢:D

尝试使用after_cancel。 为了提高效率,每次鼠标悬停时都不需要创建 Toplevel text.Just 将 -alpha 设置为 0.

import tkinter as tk
import time


class ToolTips():
    def __init__(self, widget, text, triggerkey='<Enter>', releasekey='<Leave>'):
        self.widget = widget
        self.text = text
        self.bg = '#ffffe0'
        self.widget.bind(triggerkey, self.add)
        self.widget.bind(releasekey, self.remove)
        self.widget.bind('<ButtonPress>', self.remove)
        self.hide_status = None

        self.master = tk.Toplevel(bg=self.bg)
        self.master.overrideredirect(1)
        self.master.attributes('-topmost', True)
        self.frame = tk.Frame(self.master, bg=self.bg, highlightbackground="black", highlightcolor="black",
                              highlightthickness=1)
        self.frame.pack()
        self.label = tk.Label(self.frame, text=self.text, bg=self.bg, justify=tk.LEFT)
        self.label.pack(padx=1, pady=3)
        self.master.attributes('-alpha', 0)

    def add(self, event):
        self.master.attributes('-alpha', 1)
        self.master.geometry(f'+{event.x_root}+{event.y_root}')

    def remove(self, event, alpha=1):
        if alpha > 0:
            alpha -= 0.01
            self.master.attributes('-alpha', alpha)
            if self.hide_status:
                self.master.after_cancel(self.hide_status)
            self.hide_status = self.master.after(10, lambda : self.remove(event=None, alpha=alpha))
        else:
            self.master.attributes('-alpha', 0)


# USAGE OF CLASS
root = tk.Tk()

l = tk.Label(root, text='Hover', font=('hevletica', 21))
l.pack()
l.focus_force()

obj = ToolTips(l, text='There is alot more to this? Are you curious?\nBla Bla...')

root.mainloop()

您 运行 遇到的问题是您在确定最后一个被销毁之前创建了一个新的工具提示。因此,您的参考有时可能会丢失。为避免这种情况,您需要在制作新的之前跟踪最近的并销毁它。

import tkinter as tk
import time

class ToolTips():
    def __init__(self,widget,text,triggerkey='<Enter>',releasekey='<Leave>'):
        self.widget = widget
        self.text = text
        self.bg = '#ffffe0'
        self.widget.bind(triggerkey,self.add)
        self.widget.bind(releasekey,self.remove)
        self.widget.bind('<ButtonPress>',self.remove)
        self.recent = None
        
    def add(self,event):
        if self.recent != None:
            self.recent.destroy()
        self.master = tk.Toplevel(bg=self.bg)
        self.master.geometry(f'+{event.x_root}+{event.y_root}')
        self.master.overrideredirect(1)
        self.master.attributes('-topmost',True)
        self.frame = tk.Frame(self.master,bg=self.bg,highlightbackground="black", highlightcolor="black", highlightthickness=1)
        self.frame.pack()
        self.label = tk.Label(self.frame,text=self.text,bg=self.bg,justify=tk.LEFT)
        self.label.pack(padx=1,pady=3)
        self.recent=self.master
    
    def remove(self,*args):
        alpha = self.master.attributes('-alpha')
        if alpha > 0:
            alpha -= 0.5
            self.master.attributes('-alpha',alpha)
            self.master.after(100,self.remove)
        else:
            self.master.destroy()

#USAGE OF CLASS
root = tk.Tk()

l = tk.Label(root,text='Hover',font=('hevletica',21))
l.pack()
l.focus_force()

obj = ToolTips(l,text='There is alot more to this? Are you curious?\nBla Bla...')

root.mainloop()