10

私は試してみましたが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();
}

メインウィンドウ.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;
};

メインウィンドウ.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 はおそらく内部で同様の方法でこれを行いますが、おそらくより効果的です。

4

3 に答える 3

14

ちょうど今同じ問題がありました。QFileSystemWatcher は、ファイルが変更されただけでも削除されたと考えているようです。少なくとも Linux ファイル システムでは。私の簡単な解決策は次のとおりです。

if (QFile::exists(path)) {
    watcher->addPath(path);
}

上記を のハンドラに追加しますfileChanged()。必要に応じて単語watcherを変更します。

于 2013-08-18T23:04:11.583 に答える
13

LinuxでQt5を使用しても同じ問題がありました。理由がわかりました:

kate などの一部のテキスト エディターは、ファイルの内容を変更せず、元のファイルを新しいファイルに置き換えます。ファイルを置き換えると古いファイル (IN_DELETE_SELFイベント) が削除されるため、qt はファイルの監視を停止します。

解決策は、作成イベントのファイルのディレクトリも監視することです。

于 2015-05-06T12:01:14.483 に答える
4

現在の Qt5 と Linux での問題を確認できます。Peter の回答に加えて、次のコードをスロット関数の最後に追加することで、この問題を解決しました。

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

パスをすぐに追加すると、多くの場合、ファイルがまだ存在しないことに注意してください。警告が表示され、何も追加されず、ウォッチャーはこのパスを失います。したがって、ファイルが再び生き返るまで待機/スリープしてから追加する必要があります。

また、この例では C++11 を使用し、スリープを実現するために and を含めたことにも注意してください。

于 2014-11-27T12:17:14.897 に答える