How to use QFileSystemWatcher to monitor a folder for change
Please have a look at this .h and .cpp , it shows the example... cheers !
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QWidget>
#include <QMessageBox>
class MyClass : public QWidget
{
Q_OBJECT
public:
MyClass(QWidget* parent=0)
:QWidget(parent){}
~MyClass(){}
public slots:
void showModified(const QString& str)
{
Q_UNUSED(str)
QMessageBox::information(this,"Directory Modified", "Your Directory is modified");
}
};
#endif // MYCLASS_H
#include <QApplication>
#include <QFileSystemWatcher>
#include <QDebug>
#include "MyClass.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QFileSystemWatcher watcher;
watcher.addPath("C:/QtTest");
QStringList directoryList = watcher.directories();
Q_FOREACH(QString directory, directoryList)
qDebug() << "Directory name" << directory <<"\n";
MyClass* mc = new MyClass;
QObject::connect(&watcher, SIGNAL(directoryChanged(QString)), mc, SLOT(showModified(QString)));
return app.exec();
}
When ever you modify, or create or delete a file or folder within "C:/QtTest" path you will get a message box.
Qt QFileSystemWatcher: signal fileChanged() gets emited only once
Had the same problem just now. Seems like QFileSystemWatcher thinks that the file is deleted even if it's only modified. Well at least on Linux file system. My simple solution was:
if (QFile::exists(path)) {
watcher->addPath(path);
}
Add the above to your handler of fileChanged()
. Change the word watcher
as necessary.
Qt: check if a file in folder is changed
You need to use the QFileSystemWatcher.
More importantly, this is the signal you need to connect to:
void QFileSystemWatcher::fileChanged(const QString & path) [signal]
This signal is emitted when the file at the specified path is modified, renamed or removed from disk.
See also directoryChanged().
So, you could write something like this in your class or function:
...
QFileSystemWatcher watcher;
watcher.addPath("/My/Path/To/The/File");
QObject::connect(&watcher, SIGNAL(fileChanged(const QString&)), receiver, SLOT(handleFileChanged(const QString&)));
...
QFileSystemWatcher locks directory on Windows
This is a bug in QFileSystemWatcher as discussed here
After days of trying, I am finally able to find the solution of my problem by using Win32 API for watching directories on Windows platform. I wrote a blog post on How to use Win32 Api to monitor directory changes. I would like to share the link so it may help others who land up here to find the solution of the same problem.
Win32 API to monitor Directory Changes
How to only emit one directoryChanged signal with QFileSystemWatcher
The solution is to simply avoid connecting the directoryChanged
signal to the slot that updates the images. Instead, just set a flag whenever any changes occur, and then periodically check the flag to see if any updates are needed (this can be done with a simple timer mechanism).
Here's a basic script that demonstrates the idea:
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_())
QFileSystemWatcher working only in main()
In the second case, your QFileSystemWatcher watcher
is created on the stack and is destroyed as soon as the constructor ends. You have to keep a reference to it somewhere, possibly as an attribute of your SystemFileWatcher
class
Related Topics
Why Default Return Value of Main Is 0 and Not Exit_Success
Extern "C" Linkage Inside C++ Namespace
Are There Tools That Help Organizing #Includes
Does the Alignas Specifier Work with 'New'
Warning: Narrowing Conversion C++11
Why Can't Operator () of Stateless Functor Be Static
Thread Safety of Matlab Engine API
Can This MACro Be Converted to a Function
How to Define Thread-Local Local Static Variables
How to Wrap Functions with the '--Wrap' Option Correctly
How to Prevent Screen-Savers and Sleeps During My Program Execution
How to Append to a File with Fstream Fstream::App Flag Seems Not to Work
Performance of Std::Function Compared to Raw Function Pointer and Void* This