Python 在 Windows 上提示文本消息的实现(模拟安卓手机上的 Toast 效果)

用 tkinter 实现,在桌面上即时显示文字消息(置顶显示、可拖动),经过 duration 毫秒后消失。

效果演示:

image

代码实现:


"""

使用方法:
toast(message_text, bg="#075077", duration=3000)

"""

import threading
import time
import tkinter as tk
from queue import Queue

import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(1)

class ToastMessageManager:
    _instance = None
    _lock = threading.Lock()
    
    def __new__(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super().__new__(cls)
                cls._instance.initialized = False
            return cls._instance
    
    def __init__(self):
        if not self.initialized:
            self.message_queue = Queue()
            self.manager_thread = None
            self.is_running = False
            self.initialized = True
            self.start_manager()
    
    def start_manager(self):
        """启动消息管理器"""
        if not self.is_running:
            self.is_running = True
            self.manager_thread = threading.Thread(target=self._run_manager)
            self.manager_thread.daemon = True
            self.manager_thread.start()
    
    def _run_manager(self):
        """在单独线程中运行消息管理器"""
        while self.is_running:
            try:
                # 等待消息
                text, font_size, bg, duration = self.message_queue.get(timeout=0.1)
                
                # 创建并显示窗口
                self._create_and_show_window(text, font_size, bg, duration)
                
            except:
                # 超时或其他异常,继续循环
                pass
    
    def _create_and_show_window(self, text, font_size, bg, duration):
        """创建并显示浮动消息窗口"""
        # 创建新的Tkinter根窗口
        
        root = tk.Tk()
        root.tk.call('tk', 'scaling', 2)

        
        # 设置窗口属性
        root.overrideredirect(True)
        root.attributes('-topmost', True)
        root.configure(bg=bg)

        # 绑定可拖动
        self.root = root
        root.bind('<Button-1>', self._on_drag_start)
        root.bind('<B1-Motion>', self._on_drag_motion)
        
        # 创建文字标签
        label = tk.Label(
            root,
            text=text,
            font=('Microsoft YaHei', font_size),
            fg='white',
            bg=bg,
            justify=tk.LEFT,
            wraplength=1200
        )
        label.pack(padx=20, pady=15)

        
        # 更新窗口以确保获取正确的尺寸
        root.update_idletasks()
        
        # 设置窗口位置
        self._set_window_position(root)
        
        # 显示窗口
        root.deiconify()
        
        # 设置定时器,在指定时间后销毁窗口
        root.after(duration, lambda: self._destroy_window(root))
        
        # 启动Tkinter主循环
        root.mainloop()
    
    def _set_window_position(self, root):
        """设置窗口位置"""
        try:
            screen_width = root.winfo_screenwidth()
            screen_height = root.winfo_screenheight()
            
            window_width = root.winfo_width()
            window_height = root.winfo_height()
            
            x = (screen_width - window_width) // 2
            y = screen_height // 10 * 8
            
            root.geometry(f'+{x}+{y}')
        except:
            pass
    
    def _on_drag_start(self, event):
        self.x = event.x
        self.y = event.y

    def _on_drag_motion(self, event):
        deltax = event.x - self.x
        deltay = event.y - self.y
        x = self.root.winfo_x() + deltax
        y = self.root.winfo_y() + deltay
        self.root.geometry(f"+{x}+{y}")
    
    def _destroy_window(self, root):
        """销毁窗口"""
        try:
            root.quit()  # 退出主循环
            root.destroy()  # 销毁窗口
        except:
            pass
    
    def add_message(self, text, font_size, bg, duration):
        """添加消息到队列"""
        self.message_queue.put((text, font_size, bg, duration))
    

def toast(text, font_size=14, bg="#C41529", duration=2000):
    """显示浮动消息的便捷函数"""
    manager = ToastMessageManager()
    manager.add_message(text, font_size, bg, duration)

# 使用示例
if __name__ == "__main__":
    message_text = """21:14:13 【国际航协:中国四大航空公司加入航班数据交互项目】 财联社11月14日电,从国际航协获悉,中国东方航空公司宣布加入国际航协航班计划数据交互项目(SDEP)。至此,该计划已涵盖中国四大航空公司——中国国际航空公司、中国东方航空公司、中国南方航空公司和海南航空公司,标志着该计划在中国市场的推进迈出了重要一步。随着中国四大航空公司加入航班计划数据交互项目,该项目目前涵盖了中国民航75%以上的运力。 (证券时报)"""
    toast(message_text, bg="#075077", duration=3000)
    time.sleep(4)
    toast(message_text, bg="#C41529", duration=1000)
    time.sleep(2)

posted @ 2025-11-15 01:05  淳帅二代  阅读(0)  评论(0)    收藏  举报