所以我有一个小脚本监视文件的更改/修改,如果文件被更改它会做一堆东西,如:
class Event(LoggingEventHandler): def dispatch(self, event): #Do something here if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S') event_handler = Event() observer = Observer() observer.schedule(event_handler, my_path, recursive=True) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
而且效果很好.但我有另一个脚本与一堆Tkinter小部件(典型的tk应用程序mainloop()
).现在,当用户按下某个按钮时,我想调用看门狗监视文件更改,就像之前一样,调用dispatch()
它会对它做一堆事情,并在同一个脚本中更新一些tkinter ui小部件,比如progressbars.
这个GUI的东西很新,无法弄清楚如何使看门狗循环和root.mainloop
一起工作.怎么做到呢?
Watchdog在自己的线程中运行,因此您不需要做太多事情.如果要根据事件修改GUI,则应设置线程安全队列.Tkinter小部件不应该由多个线程修改,因此常见的模式是使用线程安全队列在线程之间进行通信.
以下示例将一个监视程序事件放在队列上,并event_generate
在检测到监视程序事件时用于从观察者向GUI发送信号.我绝对不确定以下内容在所有情况下都能正常工作,因为我现在只能访问一个linux盒来测试它.但是,它似乎在Linux上运行正常.
import Tkinter as tk from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler from Queue import Queue import sys class CustomHandler(FileSystemEventHandler): def __init__(self, app): FileSystemEventHandler.__init__(self) self.app = app def on_created(self, event): app.notify(event) def on_deleted(self, event): app.notify(event) def on_modified(self, event): app.notify(event) def on_moved(self, event): app.notify(event) class App(object): def __init__(self): path = sys.argv[1] if len(sys.argv) > 1 else "/tmp" handler = CustomHandler(self) self.observer = Observer() self.observer.schedule(handler, path, recursive=True) self.queue = Queue() self.root = tk.Tk() self.text = tk.Text(self.root) self.text.pack(fill="both", expand=True) self.text.insert("end", "Watching %s...\n" % path) self.root.bind("", self.shutdown) self.root.bind("< >", self.handle_watchdog_event) self.observer.start() def handle_watchdog_event(self, event): """Called when watchdog posts an event""" watchdog_event = self.queue.get() print("event type:", type(watchdog_event)) self.text.insert("end", str(watchdog_event) + "\n") def shutdown(self, event): """Perform safe shutdown when GUI has been destroyed""" self.observer.stop() self.observer.join() def mainloop(self): """Start the GUI loop""" self.root.mainloop() def notify(self, event): """Forward events from watchdog to GUI""" self.queue.put(event) self.root.event_generate("< >", when="tail") app = App() app.mainloop()