Изменения файлов, сгенерированные Python, не обнаруживаются QFileSystemModel

Используя PyQt и Python, я столкнулся со следующей проблемой:

  1. Настройте QFileSystemModel, вызовите setRootPath () и подключитесь к сигналу dataChanged.
  2. Откройте новый файл из Python и напишите в него текст. Затем закройте его.
  3. Снова откройте файл в режиме добавления и напишите в него еще немного текста. Затем закройте его.
  4. Откройте файл во внешнем редакторе. Напишите что-нибудь. Сохранить. Пишите больше. Сохранить.

Если вы сделаете (3), сигнал dataChanged НЕ испускается. Однако, если вы выполните (4), сигнал dataChanged будет испускаться.

Какие-нибудь подсказки? Ниже приведен фрагмент кода, который воспроизводит проблему.

С наилучшими пожеланиями,

Мадс

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_())

Вот еще несколько общих наблюдений:

Основная проблема в том, что QFileSystemModel явно не отслеживает изменения файлов должным образом:

Случай 1 (Ubuntu):

1) Запустите сценарий в фоновом режиме как 'python fsm.py &' 2) Запустите приглашение Python в том же каталоге, в котором был запущен сценарий 3) Введите:

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

Новый файл определяется моделью QFileSystemModel при вызове open (). Однако модификации файлов, вызванные f.write () и f.close (), НЕ обнаруживаются.

Случай 2 (Ubuntu):

1) Пока скрипт fsm.py все еще запущен, откройте новый файл с помощью внешнего редактора (gedit, emacs и т. Д.) 2) Напишите что-нибудь и сохраните

В этом случае обнаруживается и новый файл, и модификация. Это первое, чего я не понимаю. Почему ввод-вывод Python не обнаруживается, а ввод-вывод из редактора обнаруживается?

Случай 3 (Ubuntu):

Используя Ubuntu: я запускаю файловый браузер Nautilus и повторяю шаги 1-3 из случая 1-2. Затем наутилус обнаруживает и новый файл, и модификацию. Таким образом, осуществляется мониторинг ввода-вывода, созданного Python, но, по-видимому, с использованием системы мониторинга файлов GNOME.

Случай 1 (Windows 7):

Такое же поведение.

Случай 2 (Windows 7):

Если используется Блокнот или Wordpad, модификации файлов НЕ обнаруживаются. Если используется GVim 7.3, изменения в файлах ОБНАРУЖИВАЮТСЯ.

Случай 3 (Windows 7):

При запуске собственного файлового браузера Windows 7 обнаруживаются все моды из случая 1-2.

Можете ли вы понять это?


person repoman    schedule 22.05.2012    source источник
comment
Быстрая догадка: редактор не добавляет, а заменяет файл?   -  person Martijn Pieters    schedule 22.05.2012
comment
Запустив этот код, я получаю dataChanged. Возможно, это зависит от версии Python и / или ОС. Я пробовал с Python 2.7, PyQt 4.9.1, Qt 4.8.1 на Ubuntu.   -  person Avaris    schedule 22.05.2012
comment
Вы уверены, что для третьего случая dataChanged сигнал не испускается, потому что, когда я запускал ваш код, это был результат моего первого запуска, и я получил сигнал dataCHanged, и когда я попытался внести другие изменения в файл, то есть путем редактирования в блокноте, сигнал dataChanged не был испущен.   -  person RanRag    schedule 22.05.2012
comment
Сигнал dataChanged выдается изначально, но не для файла, открытого кодом Python. Обратите внимание, что dataChanged также печатает filePath, который должен быть 'foo.dat'   -  person repoman    schedule 22.05.2012
comment
Хорошо, если я правильно вас понял, dataChanged, который выдается изначально, не предназначен для файла foo.dat. Хорошо, но, как вы упомянули, dataChanged выдается для случая 4, но, по крайней мере, не для меня. Так что для меня dataChanged сначала выдается только один раз, и после этого, что бы я ни делал, он не выдается.   -  person RanRag    schedule 22.05.2012
comment
@RanRag: Какую ОС и какой редактор вы используете?   -  person repoman    schedule 22.05.2012
comment
@Avaris: Какое имя или путь к файлу печатает dataChanged? Должен быть "foo.dat".   -  person repoman    schedule 22.05.2012
comment
Windows7, python 2.6.5, блокнот и vim.   -  person RanRag    schedule 22.05.2012
comment
@repoman: Это был не файл. Любопытно, что это был не тот каталог, в котором находился файл. Это был /home, и файл находится на несколько уровней ниже этого уровня.   -  person Avaris    schedule 22.05.2012
comment
@Avaris: / home также напечатан на моей машине. Если вы начинаете редактировать что-либо из редактора, излучается ли сигнал?   -  person repoman    schedule 22.05.2012
comment
@repoman: Modified Date не отслеживается. Измените вид на QTreeView и измените файл после отображения окна (лучше, если вы установите небольшую задержку), если хотите наблюдать. Python изменяет файл, и дата изменения фактически изменяется, но представление не обновляется. На самом деле, я не думаю, что отслеживаются отдельные файлы (возможно, это слишком дорого). При переименовании файла запускается rowsRemoved, а затем rowsInserted.   -  person Avaris    schedule 22.05.2012
comment
Привет. Спасибо за ваши комментарии. Я добавил некоторые подробности в вышеупомянутый пост. Кажется, что QFileSystemModel (или мое неправильное использование) не соответствует моим требованиям к полноценному инструменту мониторинга файлов (отслеживает все, начиная с корневого каталога и ниже). Есть ли предложения по инструменту Python, который может это сделать?   -  person repoman    schedule 23.05.2012
comment
@repoman: взгляните на qfilesystemwatcher, а также this и этот вопрос.   -  person RanRag    schedule 23.05.2012