【问题标题】:Why does QFileSystemWatcher work for directories but not files in Python?为什么 QFileSystemWatcher 适用于目录而不适用于 Python 中的文件?
【发布时间】:2012-11-22 19:28:29
【问题描述】:

我从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)

问题是,file_changed 无论如何都不会被调用。例如,directory_changed 在添加文件时会可靠地调用,但更改文件内容不会导致调用 file_changed。

我调用了QtCore.SIGNAL('fileChanged(QString)') 的一些变体,例如QtCore.SIGNAL('fileChanged(const QString &)'),但无济于事。没有警告或错误——它根本不会触发函数。

建议?

【问题讨论】:

    标签: python qt pyqt qfilesystemwatcher


    【解决方案1】:

    很难确定出了什么问题,因为示例代码不完整,因此根本无法正常工作。

    但是,假设您正在运行的真实代码或多或少健全/完整的,您的问题可能是由于没有将目录本身添加到路径列表中.

    基本脚本应如下所示:

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

    【讨论】:

    • 你是对的,虽然我的问题是没有将文件添加到路径列表中。我误解了这个类不是递归的。
    • 在调用file_changed的情况下,更新模型或QTreeView以显示更新文件的方式是什么。就我而言,当我知道它已更改时,我想查看更新的日期/时间戳。我有一个编译按钮,我希望新的 .mpy 文件显示更新的时间戳
    • @Eradicatore。请提出一个新问题。
    • 好的,当然。如果我的问题已经涵盖了,我不想创建新的,但我现在会这样做。
    • 我在这里问了我的问题,仅供参考:stackoverflow.com/questions/44839096/…
    【解决方案2】:
    import argparse
    import configparser
    import os
    import sys
    
    from PyQt5 import QtCore
    from PyQt5.QtGui import QIcon
    from PyQt5.QtWidgets import QApplication, QDesktopWidget, QMessageBox
    from PyQt5.QtWidgets import QMainWindow
    
    from ProgressBar_ui import Ui_Form
    
    
    class ProgressBarWindow(QMainWindow, Ui_Form):
        def __init__(self):
            super().__init__()
            self.ui = Ui_Form()
            self.ui.setupUi(self)
            self.ui.progressBar.setMinimum(0)
            self.ui.progressBar.setMaximum(0)
            self.ui.progressBar.setValue(0)
            self.setWindowTitle("Progress Bar")
            self.MSversion = ""
            self.LOADING_LOG_PATH = ""
            mainIco = ("Icons\myIcon.ico")
            self.setWindowIcon(QIcon(mainIco))
            self.ui.label.setText("")
            self.ui.label.setWordWrap(True)
    
    
    
        def location_on_the_screen(self):
            ag = QDesktopWidget().availableGeometry()
            sg = QDesktopWidget().screenGeometry()
    
            widget = self.geometry()
            x = ag.width() - widget.width()
            y = 2 * ag.height() - sg.height() - widget.height()
            self.move(x, y)
    
    
        def file_changed(self, pathPassed):
            if os.path.exists(pathPassed):
                f = open(pathPassed, "r")
                for x in f:
                    #print(x)
                    label =x
                    self.ui.label.setText(label)
                    if x == "CloseLoading":
                        self.close()
    
    def main():
        app = QApplication(sys.argv)
        w = ProgressBarWindow()
        w.setWindowFlags(w.windowFlags() & ~QtCore.Qt.WindowMaximizeButtonHint)
    
        parser = argparse.ArgumentParser()
        parser = argparse.ArgumentParser(description='ProgressBar Arguments')
    
        parser.add_argument('version', action="store", type=str)
    
        args = vars(parser.parse_args())
    
        if len(sys.argv) < 1:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            errorMsg = "There are less than 2 command line arguments provided.\nLauncher can not be run."
            msg.setText(errorMsg)
            msg.setWindowTitle("Save paths..")
            msg.exec_()
            sys.exit()
    
    
    
        p= '/path/toFile/'
        paths = [ p ]
    
        fs_watcher = QtCore.QFileSystemWatcher(paths)
        #fs_watcher.directoryChanged.connect(w.directory_changed)
        fs_watcher.fileChanged.connect(w.file_changed)
        w.location_on_the_screen()
        w.show()
        app.exec_()
    
    if __name__ == "__main__":
        sys.exit(main())
    

    【讨论】:

    • 上面的代码,创建了一个带有progressBar和一个标签的FORM,读取一个文件并更新GUI上的标签。 QFileSystemWatcher 正在寻找文件的更新并调用 fileChanged 方法来更新标签的文本。另外,请注意观察者在 main 函数中工作,但不在任何其他类中,并且 file_changed 信号是私有信号,不能由用户发出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 2010-09-16
    • 1970-01-01
    • 2012-08-02
    • 2021-04-08
    相关资源
    最近更新 更多