Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用QFileSystemWatcher仅发出一个directoryChanged信号_Python_Pyqt_Pyside_Qfilesystemwatcher - Fatal编程技术网

Python 如何使用QFileSystemWatcher仅发出一个directoryChanged信号

Python 如何使用QFileSystemWatcher仅发出一个directoryChanged信号,python,pyqt,pyside,qfilesystemwatcher,Python,Pyqt,Pyside,Qfilesystemwatcher,以下是我申请的基本前提: 我已经建立了QFileSystemWatcher来监视目录 Path = [r'C:\Users\user\Documents\Images'] DirectoryWatcher = QtCore.QFileSystemWatcher(Path) DirectoryWatcher.directoryChanged.connect(showImages.UpdateImages) 我以前使用过QFileSystemWatcher,它总是工作得很好(对于目录和文件更改)

以下是我申请的基本前提:

我已经建立了QFileSystemWatcher来监视目录

Path = [r'C:\Users\user\Documents\Images']
DirectoryWatcher = QtCore.QFileSystemWatcher(Path)
DirectoryWatcher.directoryChanged.connect(showImages.UpdateImages)
我以前使用过QFileSystemWatcher,它总是工作得很好(对于目录和文件更改)

应用程序将在\images文件夹中显示图像的幻灯片。在\Images文件夹中放置新图像时,幻灯片将重置为包含新图像。如果从\Images文件夹中删除图像,幻灯片将再次重置

我遇到的问题是:如果我将多个图像拖到\images文件夹中,directoryChanged信号会多次触发。触发该信号,并为添加到文件夹中的每个图像运行相应的UpdateImages()例程,即使这些图像是同时添加的(即,选择多个图像,将它们拖放到\images中)

这破坏了我的日常生活。有没有办法为一批目录更改触发一次directoryChanged信号?即,在将最终图像添加到目录之前,我是否可以禁用该信号


非常感谢

解决方案是避免将
directoryChanged
信号连接到更新图像的插槽。相反,只要在发生任何更改时设置一个标志,然后定期检查该标志以查看是否需要任何更新(这可以通过简单的计时器机制完成)

下面是一个基本的脚本,演示了这个想法:

import sys, os
from PyQt4 import QtCore, QtGui

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.list = QtGui.QListWidget(self)
        self.button = QtGui.QPushButton('Choose Directory', self)
        self.button.clicked.connect(self.handleSetDirectory)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.list)
        layout.addWidget(self.button)
        self.watcher = QtCore.QFileSystemWatcher(self)
        self.watcher.directoryChanged.connect(self.handleDirectoryChanged)
        self.timer = QtCore.QTimer(self)
        self.timer.setInterval(500)
        self.timer.timeout.connect(self.handleTimer)
        self.handleSetDirectory(QtCore.QDir.tempPath())

    def handleDirectoryChanged(self):
        self.timer.stop()
        print('Directory Changed')
        self._changed = True
        self.timer.start()

    def handleSetDirectory(self, directory=None):
        if not directory:
            directory = QtGui.QFileDialog.getExistingDirectory(self)
        if directory:
            self.timer.stop()
            self.watcher.removePaths(self.watcher.directories())
            self._changed = False
            self.watcher.addPath(directory)
            self.updateList()
            self.timer.start()

    def handleTimer(self):
        if self._changed:
            self._changed = False
            self.updateList()

    def updateList(self):
        print('Update List')
        self.list.clear()
        for directory in self.watcher.directories():
            self.list.addItems(os.listdir(directory))

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(250, 600)
    window.show()
    sys.exit(app.exec_())

我不认为这些图像是同时复制的。除非您实现一些时间延迟,否则这是预期的行为。看起来没有适合您需要的信号,但您可以将
directoryChanged
连接到设置标志或具有计时器的智能函数,而不是立即更新图像。这样你就可以自己过滤事件。你也可以研究
eventFilter
,它可以让你截获和操作特定类型的事件。感谢大家的支持,非常感谢。我没有太多地使用“eventFilter”,但我可以看出这是多么有用。Windows(7,如果有区别的话)是否会“宣布”将有多少文件添加到一个目录中?如果我知道要移动的文件数量,在移动之前,我可以设置一个过滤事件,当发出directoryChanged信号时运行该事件。感谢您的评论,非常感谢(一如既往!)。我将逐行检查您的代码,但与此同时,轮询真的是唯一可行的方法吗?我并不反对在这种特殊情况下进行投票,我只是假设在已建立的信号流程周围会有更高级别的控制。再次感谢@jars121。这个问题与信号无关,甚至与Qt无关:它完全与文件系统的工作方式有关。当涉及到文件系统通知时,Qt完全依赖于操作系统。一些操作是严格原子化的(例如,在某些情况下,文件重命名),但大多数不是
QFileSystemWatcher
是一个相当基本的包装类,它隐藏了各种平台之间的大部分细节。这使得它可以方便地用于简单的任务,但它显然缺乏操作系统本身可能提供的许多细粒度控制。后来我又做了一些阅读,似乎一个“简单”事件,比如将文件复制到目录,实际上可能涉及操作系统本身发出的几个低级信号。假设Python只是读取发出的OS信号(如您所述),那么在这个实例中就没有什么可以做的了。我目前正在重新编写应用程序,以包含标志和轮询,看起来这将是一种更合适的替代方法。再次感谢!