2016-03-08 5 views
0

Mon code pour une classe qui détecte un fichier spécifique a été modifié:watchdog (Python's library) - Comment envoyer un signal lorsqu'un fichier est modifié?

class MyEventHandler(FileSystemEventHandler, QtCore.QThread): 
    def __init__(self, filename): 
     super(MyEventHandler, self).__init__() 
     self.filename = filename 

    def on_modified(self, event): 
     if not event.is_directory and event.src_path.endswith(self.filename): 
      print "modified" 
      self.emit(QtCore.SIGNAL("fileModified")) 


class WatchOutForFileModifications(QtCore.QThread): 
    def __init__(self, path, filename): 
     super(WatchOutForFileModifications, self).__init__() 
     self.path = path 
     self.filename = filename 
     self.observer = Observer() 
     self.event_handler = MyEventHandler(self.filename) 
     self.observer.schedule(self.event_handler, self.path, recursive=False) 
     self.observer.start() 

    def run(self): 
     while 1: 
      self.connect(self.event_handler, QtCore.SIGNAL("fileModified"), self.modified) 


    def modified(self): 
     self.emit(QtCore.SIGNAL("fileModified1")) 

Et l'extrait de code pour l'application elle-même:

class MainWindow(QtGui.QMainWindow): 
    def __init__(self): 
     super(MainWindow, self).__init__() 
     uic.loadUi('test.ui', self) 

     path = "somePath" 
     filename = "someName" 

     self.fileWatcher = WatchOutForFileModifications(path, filename) 
     self.fileWatcher.start() 
     self.connect(self.fileWatcher, QtCore.SIGNAL("fileModified1"), self.fileModified) 
     self.show() 

    def fileModified(self): 
     print 1 

Le problème est que lorsqu'un fichier est modifié, je obtenir un flux non-stop de 1 en cours d'impression. Je me rends compte qu'il ne devrait pas être émis/connecté de cette façon dans la classe WatchOutForFileModifications, mais je ne comprends pas comment est l'API: http://pythonhosted.org/watchdog/api.html#watchdog.observers.api.EventEmitter - supposé fonctionner. Au moins, je suppose que c'est l'API que je devrais utiliser pour écouter les modifications de fichiers.

EDIT

Code de travail après quelques modifications:

import sys de QtGui importation PyQt4, QtCore, uic

from watchdog.events import FileSystemEventHandler 
from watchdog.observers import Observer 

class MyEventHandler(FileSystemEventHandler, QtCore.QThread): 
    def __init__(self, filename): 
     super(MyEventHandler, self).__init__() 
     self.filename = filename 
     self.signalName = str(filename) + "_modified" 

    def on_modified(self, event): 
     if not event.is_directory and event.src_path.endswith(self.filename): 
      self.emit(QtCore.SIGNAL(self.signalName)) 


class FileModificationWatcher(QtCore.QThread): 
    def __init__(self, path, filename): 
     super(FileModificationWatcher, self).__init__() 
     self.path = path 
     self.filename = filename 
     self.observer = Observer() 
     self.event_handler = MyEventHandler(self.filename) 
     self.observer.schedule(self.event_handler, self.path, recursive=False) 
     self.observer.start() 

    def run(self): 
     pass 

    def getEmitter(self): 
     return self.event_handler 

    def getSignalName(self): 
     return self.event_handler.signalName 

class MainWindow(QtGui.QMainWindow): 
    def __init__(self): 
     super(MainWindow, self).__init__() 
     uic.loadUi('test.ui', self) 

     path = "somePath" 
     filename = "someName" 

     self.fileWatcher = FileModificationWatcher(path, filename) 
     self.fileWatcher.start() 
     self.connect(self.fileWatcher.getEmitter(), QtCore.SIGNAL(self.fileWatcher.getSignalName()), self.fileModified) 
     self.show() 

    def fileModified(self): 
     print 1 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 

    window = MainWindow() 
    sys.exit(app.exec_()) 

Répondre

-1

En classe vos WatchOutForFileModifications, essayez de connecter le signal dans la init méthode.

1

Le problème est que dans WatchOutForFileModifications vous connectez à plusieurs reprises le signal à l'emplacement dans la fonction d'exécution. Pour résoudre le problème que vous rencontrez, prenez l'appel self.connect et le déplacer dans la __init__ de la classe, comme ceci:

from PyQt4 import QtCore, QtGui 
from watchdog.events import FileSystemEventHandler 
from watchdog.observers import Observer 


class MyEventHandler(FileSystemEventHandler, QtCore.QThread): 
    def __init__(self, filename): 
     super(MyEventHandler, self).__init__() 
     self.filename = filename 

    def on_modified(self, event): 
     if not event.is_directory and event.src_path.endswith(self.filename): 
      print("modified") 
      self.emit(QtCore.SIGNAL("fileModified")) 


class WatchOutForFileModifications(QtCore.QThread): 
    def __init__(self, path, filename): 
     super(WatchOutForFileModifications, self).__init__() 
     self.path = path 
     self.filename = filename 
     self.observer = Observer() 
     self.event_handler = MyEventHandler(self.filename) 
     self.observer.schedule(self.event_handler, self.path, recursive=False) 
     self.observer.start() 
     self.connect(self.event_handler, QtCore.SIGNAL("fileModified"), self.modified) 

    def run(self): 
     pass 

    def modified(self): 
     self.emit(QtCore.SIGNAL("fileModified1")) 


class MainWindow(QtGui.QMainWindow): 
    def __init__(self): 
     super(MainWindow, self).__init__() 

     path = r'D:\Code\\' 
     filename = "Hexagon_Grid_Creation.py" 

     self.fileWatcher = WatchOutForFileModifications(path, filename) 
     #self.fileWatcher.start() 
     self.connect(self.fileWatcher, QtCore.SIGNAL("fileModified1"), self.fileModified) 
     self.show() 

    def fileModified(self): 
     print(1) 

if __name__ == '__main__': 
    app = QtGui.QApplication([]) 
    window = MainWindow() 
    window.show() 
    app.exec_() 

Dans ce cas, vous n'avez pas besoin probablement le QThread; le fichier est surveillé par le gestionnaire d'événements, vous n'avez donc rien d'autre à faire en arrière-plan. Je pense que vous pouvez supprimer complètement cette classe et juste instancier le gestionnaire d'événements dans la classe MainWindow.

+1

En fait, j'ai réalisé que je pouvais faire la connexion directement de 'MyEventHandler' à' MainWindow', en ignorant complètement la gestion des signaux dans 'WatchOutForFileModifications'. – emihir0