Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt QFileSystemWatcher: signal fileChanged() gets emited only once

Tags:

c++

qt

I was trying the QFileSystemWatcher out and it somehow doesn't work as expected. Or am I doing something wrong?

I've set the QFileSystemWatcher to watch a single file. When I modify the file for the first time, fileChanged() gets emited, that's OK. But when I modify the file again, fileChanged() doesn't get emited anymore.

Here is the source code:

main.cpp

#include <QApplication>

#include "mainwindow.h"

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  MainWindow window;

  window.show();

  return app.exec();
}

mainwindow.h

#include <QDebug>
#include <QFileSystemWatcher>
#include <QMainWindow>
#include <QString>

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:

  MainWindow();

private slots:

  void directoryChanged(const QString & path);
  void fileChanged(const QString & path);

private:

  QFileSystemWatcher * watcher;
};

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow()
{
  watcher = new QFileSystemWatcher(this);
  connect(watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &)));
  connect(watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
  watcher->addPath("path to directory");
  watcher->addPath("path to file");
}

void MainWindow::directoryChanged(const QString & path)
{
  qDebug() << path;
}

void MainWindow::fileChanged(const QString & path)
{
  qDebug() << path;
}

Thank you for your answers.

Edit 1

I ran this code under Linux.

Edit 2

I actually need to check all MetaPost files in a tree given by some directory, whether they were modified. I will probably stick to my alternative solution, which is to run QTimer every second and manually check all files. The QFileSystemWatcher probably does this in similar fashion internally, but probably more effectively.

like image 555
pizet Avatar asked Aug 18 '13 14:08

pizet


2 Answers

I can confirm your problem with current Qt5 and Linux. In addition to the answer given by Peter I solved this problem by adding the following code to the end of the slot-function:

QFileInfo checkFile(path);
while(!checkFile.exists())
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
watcher->addPath(path);

Note that if you add the path immediately, the file often does not exist yet, you get a warning and nothing will be added at all and the watcher looses this path. Therefore, you have to wait/sleep until the file is back to life again, then add it.

Also note that in this example I used C++11 and included and for realizing the sleep.

like image 92
SoJeN Avatar answered Sep 17 '22 00:09

SoJeN


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.

like image 37
Peter Avatar answered Sep 18 '22 00:09

Peter