Python中如何结合SysTrayIcon与文件监控循环,实现文件变化时桌面右下角图标实时更新

如题,我用多线程启动了一个桌面右下角图像显示的类和一个循环读取日志文件的函数,现在想实现当读取到文件变化时,控制右下角图标变换显示下,不知道如何实现 主要代码如下

def ReadLogFile("01.log"):

switch_icon2(SysTrayIcon)#切换右下角图标失败

t1=threading.Thread(target=SysTrayIcon,args=(icons.__next__(), hover_text, menu_options,on_quit, default_menu_index))
t1.start()#启动右下角图标程序
t2=threading.Thread(target=ReadLogFile,args=("01.log"))
t2.start()#启动右下角图标程序

代码地址: https://paste.ubuntu.com/p/H8gqZs6RPx/


Python中如何结合SysTrayIcon与文件监控循环,实现文件变化时桌面右下角图标实时更新

2 回复

要结合SysTrayIcon和文件监控循环,实现文件变化时实时更新托盘图标,可以用pystray做托盘图标,用watchdog监控文件变化。下面是一个完整的示例:

import threading
import time
from pathlib import Path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import pystray
from PIL import Image
import sys

class FileChangeHandler(FileSystemEventHandler):
    """处理文件变化事件"""
    def __init__(self, icon_update_callback):
        super().__init__()
        self.icon_update_callback = icon_update_callback
    
    def on_modified(self, event):
        if not event.is_directory:
            print(f"文件已修改: {event.src_path}")
            self.icon_update_callback()

class TrayApp:
    def __init__(self, watch_path):
        self.watch_path = Path(watch_path)
        self.icon_state = "normal"
        self.icon = None
        self.observer = None
        
        # 创建图标图像
        self.images = {
            "normal": self.create_image("normal"),
            "alert": self.create_image("alert")
        }
    
    def create_image(self, state):
        """创建图标图像"""
        if state == "normal":
            # 绿色图标
            return Image.new('RGB', (64, 64), (76, 175, 80))
        else:
            # 红色图标
            return Image.new('RGB', (64, 64), (244, 67, 54))
    
    def update_icon(self):
        """更新托盘图标"""
        if self.icon:
            self.icon.icon = self.images["alert"]
            # 3秒后恢复原状
            threading.Timer(3.0, self.reset_icon).start()
    
    def reset_icon(self):
        """恢复原始图标"""
        if self.icon:
            self.icon.icon = self.images["normal"]
    
    def setup_tray(self, icon):
        """设置托盘菜单"""
        self.icon = icon
        icon.menu = pystray.Menu(
            pystray.MenuItem("退出", self.on_exit)
        )
    
    def on_exit(self, icon, item):
        """退出程序"""
        if self.observer:
            self.observer.stop()
        icon.stop()
        sys.exit(0)
    
    def start_file_monitor(self):
        """启动文件监控"""
        event_handler = FileChangeHandler(self.update_icon)
        self.observer = Observer()
        self.observer.schedule(event_handler, str(self.watch_path), recursive=True)
        self.observer.start()
        print(f"开始监控目录: {self.watch_path}")
    
    def run(self):
        """运行应用程序"""
        # 启动文件监控线程
        monitor_thread = threading.Thread(target=self.start_file_monitor, daemon=True)
        monitor_thread.start()
        
        # 启动托盘图标
        self.icon = pystray.Icon(
            "file_monitor",
            self.images["normal"],
            "文件监控",
            self.setup_tray
        )
        self.icon.run()

if __name__ == "__main__":
    # 监控当前目录,你可以改成需要监控的路径
    app = TrayApp(".")
    app.run()

安装依赖:

pip install pystray pillow watchdog

工作原理:

  1. FileChangeHandler 类监控文件变化,检测到修改时调用回调函数
  2. TrayApp 类管理托盘图标和文件监控
  3. 文件变化时,图标会变成红色3秒,然后恢复绿色
  4. 右键托盘图标可以退出程序

使用说明:

  • 修改 TrayApp(".") 中的路径为你需要监控的目录
  • 运行后会在系统托盘显示图标
  • 监控目录中的文件被修改时,图标会变色提示

这个方案用两个线程分别处理托盘图标和文件监控,互不干扰。你可以根据需要修改图标样式、监控事件类型或添加更多功能。

总结:用watchdog监控文件,pystray显示托盘图标,通过线程间通信更新状态。


想弄个全局函数 因为 SysTrayIcon(icons.next(), hover_text, menu_options,on_quit, default_menu_index) 是阻塞的,没法实现,在 启动 SysTrayIcon ()时候把函数传给读文件的函数 ReadLogFile ()好像也无法实现

回到顶部