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