Python generated file changes not detected by QFileSystemModel

856 Views Asked by At

Using PyQt and Python I came across the following issue:

  1. Set up a QFileSystemModel, call setRootPath() and hook up to the dataChanged signal.
  2. Open a new file from Python and write some text into it. Then close it.
  3. Reopen the file in append mode and write some more text into it. Then close it.
  4. Open a file in an external editor. Write some stuff. Save. Write more stuff. Save.

If you do (3), the dataChanged signal is NOT emitted. However, if you do (4), the dataChanged signal IS emitted.

Any clues? A code snippet that reproduces the issue is included below.

Best regards,

Mads

import sys
import os

from PyQt4 import QtGui, QtCore

class Widget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        layout = QtGui.QVBoxLayout()
        self.setLayout(layout)
        self._view = QtGui.QListView()
        layout.addWidget(self._view)

        # Add the model
        self._model = QtGui.QFileSystemModel()
        self._model.setRootPath(QtCore.QDir().rootPath())
        self._model.setReadOnly(False)
        self._model.setFilter(QtCore.QDir.AllDirs | QtCore.QDir.AllEntries)        
        self._view.setModel(self._model)

        # Root path
        path = os.path.dirname(os.path.abspath(__file__))
        self._model.setRootPath(path)

        # Set a root index
        index = self._model.index(path)
        self._view.setRootIndex(index)

        # Generate a file with some text
        print 'Making file'
        f = open('foo.dat', 'w')
        f.write('Some stuff\n')
        f.close()

        self.connect(self._model, QtCore.SIGNAL('dataChanged(const QModelIndex &, const QModelIndex &)'), self.dataChanged)

        # Append more text - this should trigger a signal call
        print 'Modifying file'
        f = open('foo.dat', 'w+')
        f.write('Some more stuff\n')
        f.close()

    def dataChanged(self, index_0, index_1):
        print 'dataChanged', self._model.filePath(index_0), self._model.filePath(index_1)

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

    widget = Widget()
    widget.show()

    sys.exit(app.exec_())

Here are some more general observations:

The basic problem is that QFileSystemModel apparently does not monitor file changes in a proper way:

Case 1 (Ubuntu):

1) Run the script in the background as 'python fsm.py &' 2) Launch a Python prompt in the same directory where the script was started in 3) Type:

f = open('foo.txt', 'w')
f.write('eyeyehydhdhdhdhdhdhhdhdshshs')
f.close()

The new file IS detected by the QFileSystemModel when open() is called. However, the file modifications caused by f.write() and f.close() are NOT detected.

Case 2 (Ubuntu):

1) While the script 'fsm.py' is still running, open a new file using some external editor (gedit, emacs, etc.) 2) Write some stuff and save

In this case, both the new file and the modification are detected. This is the first thing I don't understand. How come Python IO is not detected but IO from an editor is?

Case 3 (Ubuntu):

Using Ubuntu: I launch the Nautilus file browser and repeat step 1-3 from Case 1-2. Then both the new file and the modification are detected by nautilus. So there Python generated IO is monitored, but apparently using GNOME file monitoring system.

Case 1 (Windows 7):

Same behavior.

Case 2 (Windows 7):

If Notepad or Wordpad is used, file modifications are NOT detected. If GVim 7.3 is used, file modifications ARE detected.

Case 3 (Windows 7):

Launching the native Windows 7 file browser, all mods from Case 1-2 are detected.

Can you make any sense out of this?

0

There are 0 best solutions below