你怎么知道在正在运行的Python中修改文件的时间?

时间:2015-06-15 22:55:34

标签: windows pyqt4

我有一个Python / PyQt应用程序,它将许多文件引用加载到内存中,并通知用户每个文件中的信息(文本)。它甚至允许用户使用Popen打开编辑器(在我的情况下为vim)。我希望该程序列出它在QTreeView中打开的所有文件,用mtime标记一个复选框,如果比应用程序的开始更新。我知道如何获取文件的mtime。我想要做的是知道文件是否已更新(修改 - Windows操作系统)并更改复选框状态以反映文件现在已修改(脏)的事实。在我看来,我可以通过运行一个单独的线程(或没有显示任何内容的QDialog?)来做到这一点。但这需要一个进程来持续在文件列表上进行getmtime并与MainWindow进行通信。可能是轮询循环中有一些睡眠,以免占用太多周期,但这会带来其他问题。我真的希望操作系统发出file_change,但我不认为这是一个可能的解决方案。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

watchdog,它监视几个平台上的文件系统更改,包括窗口。

如果您想自己动手,这里使用的机制,对于Windows上的非轮询监控,是ReadDirectoryChangesW API函数

或者,有FindFirstChangeNotification API调用,对于某些用例来说,这种调用稍微复杂一些。

Here是一篇关于在Windows上使用所有这些例程的好文章,在python中。

答案 1 :(得分:0)

从其他地方使用FindFirstChange的建议让我朝着我想要的方向前进。我的答案是使用PyQt4的QFileSystemWatcher。这提供了我想要的功能,并与Qt更紧密地集成。以下是如何使用QFileSystemWatcher监视文件和目录的示例。现在我可以扩展路径/文件以检查并询问哪些是受监控的。这缺乏很多错误检查,但它是一个从头开始工作的存根。

import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
from os import curdir

class MainWindow(QtGui.QMainWindow):
    path_Sig = QtCore.SIGNAL('pathsAdd()')
    def __init__(self):
        super(MainWindow, self).__init__()
        self.path = ['./test.dat', 'local1.bdf', 'Sub/sub1.bdf']
        button = QtGui.QPushButton('Paths')
        self.label = QtGui.QLabel(curdir)
        widget = QtGui.QWidget()
        layout = QtGui.QVBoxLayout(widget)
        layout.addWidget(button)
        layout.addWidget(self.label)
        self.setCentralWidget(widget)
        self.connect(button, QtCore.SIGNAL('clicked()'), self.setPaths)

    @QtCore.pyqtSlot(list)
    def setPaths(self):
        self.emit(QtCore.SIGNAL('path_Sig'), self.path)
        self.myPaths(self.path)
    @QtCore.pyqtSlot(list)
    def myPaths(self, path_list):
        self.label.setText(str().join(path_list))
    @QtCore.pyqtSlot("QString")
    def dirChanged(self, results):
        self.label.setText("Dir  {} changed".format(results))
    @QtCore.pyqtSlot("QString")
    def fileChanged(self, results):
        self.label.setText("File {} changed".format(results))

class FileWatcher(QtCore.QFileSystemWatcher):
    these_Sig = QtCore.SIGNAL('myPaths()')
    def __init__(self, paths=None):
        super(FileWatcher, self).__init__()
        try:
            self.addPaths(paths)
        except:
            self.addPath(curdir)

    @QtCore.pyqtSlot()
    def filesReport(self):
        self.emit(QtCore.SIGNAL('these_Sig'), self.files())
    @QtCore.pyqtSlot(list)
    def pathsAdd(self, path_list):
        self.addPaths(path_list)
        self.filesReport()

 if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('FileWatcherDemo')
    window = MainWindow()
    window.show()
    filewatcher = FileWatcher()
    QtCore.QObject.connect(filewatcher, QtCore.SIGNAL('directoryChanged(QString)'), window, QtCore.SLOT('dirChanged(QString)'))
    QtCore.QObject.connect(filewatcher, QtCore.SIGNAL('fileChanged(QString)'), window, QtCore.SLOT('fileChanged(QString)'))
    QtCore.QObject.connect(filewatcher, QtCore.SIGNAL('these_Sig'), window.myPaths)
    QtCore.QObject.connect(window, QtCore.SIGNAL('path_Sig'), filewatcher.pathsAdd)
    sys.exit(app.exec_())