Search code examples
c++qtqfilesystemmodelqfilesystemwatcher

QFileSystemModel doesn't emit fileRenamed signal


I am trying to watch the changes in a directory using QFileSystemModel. Whenever I rename a file in the root path, only the directoryLoaded() signal is emitted. I want the fileRenamed() signal to be emitted so that I know which file is renamed to a new name. Here is my code:

model = new QFileSystemModel;
model->setRootPath("C:/test/");
QObject::connect(model, SIGNAL(fileRenamed(const QString&, const QString&, const QString&)), this, SLOT(updateRename()));
QObject::connect(model, SIGNAL(directoryLoaded(const QString&)), this, SLOT(loadDir()));

Solution

  • I am afraid you expect too much from this QFileSystemModel class. It does not and cannot catch if the renaming operation happens outside of the model. I looked up all uses of fileRenamed() signal and it seems that the only place where it is emitted is here: https://code.woboq.org/qt5/qtbase/src/widgets/dialogs/qfilesystemmodel.cpp.html#933

    And if you go a few lines above, you can see that this is triggered when the renaming happens inside this function https://code.woboq.org/qt5/qtbase/src/widgets/dialogs/qfilesystemmodel.cpp.html#873 In other words, if you use QFileSystemModel::setData() to set a name to an item, it will rename the item and emit the signal. And it is the only way to have the signal emitted.

    And this is logical, if renaming happens outside of your program, then there is no certain way to find out that a certain file was renamed. Your application only observes that some file disappeared and another file with a different name emerged. Of course, you can check whether the timestamp and size of the file is the same, whether they are also in the same parent folder, maybe also check the file content... and only if these things match and the only difference is in the file names, then you can conclude that the file was renamed. But this is something you must program yourself. QFileSystemModel will not do it for you because it does not know your specific intentions.