Search code examples
pythonqtpyqtqfilesystemwatcher

Why does QFileSystemWatcher work for directories but not files in Python?


I borrowed this code from another StackOverflow answer:

from PyQt4 import QtCore

@QtCore.pyqtSlot(str)
def directory_changed(path):
    print('Directory Changed!!!')

@QtCore.pyqtSlot(str)
def file_changed(path):
    print('File Changed!!!')

fs_watcher = QtCore.QFileSystemWatcher(['/path/to/files_1', '/path/to/files_2', '/path/to/files_3'])

fs_watcher.connect(fs_watcher, QtCore.SIGNAL('directoryChanged(QString)'), directory_changed)
fs_watcher.connect(fs_watcher, QtCore.SIGNAL('fileChanged(QString)'), file_changed)

The problem is, file_changed never gets called, no matter what. directory_changed is reliably called when a file is added, for example, but changing the files content does not result in file_changed being called.

I called a few variations of QtCore.SIGNAL('fileChanged(QString)'), eg, QtCore.SIGNAL('fileChanged(const QString &)'), to no avail. There are no warnings, or errors -- it simply does not trigger the function.

Recommendations?


Solution

  • It's hard to be certain what's going wrong, because the example code is incomplete, and so cannot work at all as it stands.

    However, assuming the real code you are running is more or less sane/complete, your problem is probably caused by not adding the directory itself to the list of paths.

    A basic script should look something like this:

    import sys
    from PyQt4 import QtCore
    
    def directory_changed(path):
        print('Directory Changed: %s' % path)
    
    def file_changed(path):
        print('File Changed: %s' % path)
    
    app = QtCore.QCoreApplication(sys.argv)
    
    paths = [
        '/path/to',
        '/path/to/files_1',
        '/path/to/files_2',
        '/path/to/files_3',
        ]
    
    fs_watcher = QtCore.QFileSystemWatcher(paths)
    fs_watcher.directoryChanged.connect(directory_changed)
    fs_watcher.fileChanged.connect(file_changed)
    
    sys.exit(app.exec_())