Qt QFileSystemWatcher:信号fileChanged()仅发出一次

时间:2013-08-18 14:57:56

标签: c++ qt

我正在尝试QFileSystemWatcher,但它不能按预期工作。或者我做错了什么?

我已将QFileSystemWatcher设置为观看单个文件。当我第一次修改文件时,fileChanged()被激活,这没关系。但是当我再次修改文件时,fileChanged()不再被激活。

以下是源代码:

的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;
}

感谢您的回答。

修改1

我在Linux下运行此代码。

修改2

我实际上需要检查某个目录给出的树中的所有MetaPost文件,无论它们是否被修改。我可能会坚持我的替代解决方案,即每秒运行QTimer并手动检查所有文件。 QFileSystemWatcher可能在内部以类似的方式执行此操作,但可能更有效。

3 个答案:

答案 0 :(得分:10)

刚才有同样的问题。好像QFileSystemWatcher认为即使文件被修改也会被删除。至少在Linux文件系统上。我的简单解决方案是:

watcher->addPath(path);

将上述内容添加到fileChanged()的处理程序中。根据需要更改单词watcher

[编辑]删除了QFile :: exists(),用addPath()处理。

答案 1 :(得分:9)

我在Linux上使用Qt5时遇到了同样的问题。找出原因:

某些文本编辑器(如kate)不会修改文件的内容,而是用新文件替换原始文件。替换文件将删除旧文件(IN_DELETE_SELF事件),因此qt将停止观看该文件。

解决方案是还要监视文件的创建事件目录。

答案 2 :(得分:3)

我可以用当前的Qt5和Linux来确认你的问题。 除了Peter给出的答案之外,我还通过在slot-function的末尾添加以下代码来解决这个问题:

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

请注意,如果您立即添加路径,该文件通常不存在,您会收到警告,并且根本不会添加任何内容,并且观察者会丢失此路径。因此,您必须等待/休眠,直到文件再次恢复生命,然后添加它。

另请注意,在此示例中,我使用了C ++ 11并包含并用于实现睡眠。