Python 在 Windows 上提示文本消息的实现(模拟安卓手机上的 Toast 效果)
用 tkinter 实现,在桌面上即时显示文字消息(置顶显示、可拖动),经过 duration 毫秒后消失。
效果演示:

代码实现:
"""
使用方法:
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)

浙公网安备 33010602011771号