如何在文件通过另一个进程更改后刷新QTreeView中的QFileSystemModel?
我有一个QTreeView
作为模型QFileSystemModel
。文件和目录加载正确。如何在文件通过另一个进程更改后刷新QTreeView中的QFileSystemModel?
在我的应用程序工作流程中,不同的进程会复制并覆盖文件系统上的文件。
但是,我的QTreeView
不会更新覆盖文件的项目/行(例如:文件的大小和lastModified值不更新为新值)。
使用文件路径,我可以得到一个FileInfo
,它具有更新的lastModified值。但是,使用该相同路径来获取该行的lastModified值的QModelIndex
会导致它返回旧值。
我试过几件事(见下文)无济于事。
请让我知道你是否知道如何解决这个问题。非常感谢! :)
// ... at this point the file system has been updated and the file
// has new values for things like last modified date
QFileInfo *updatedFile = new QFileInfo(filePath);
QModelIndex indexOfFileName = myFileTreeView->myFileSystemModel->index(filePath);
QModelIndex indexOfLastModifiedDate = myFileTreeView->myFileSystemModel->index(filePath, lastModifiedColumnIndex);
// attempts to kick the QFileSystemModel and QTreeView to update the model values
// a collection from the internet :)
emit myFileTreeView->dataChanged(indexOfFileName, indexOfLastModifiedDate);
emit myFileTreeView->myFileSystemModel->dataChanged(indexOfFileName, indexOfLastModifiedDate);
myTreeView->repaint();
myTreeView->update(indexOfLastModifiedDate);
myTreeView->viewport()->update();
// looking to see if values changed
QModelIndex newIndexOfLastModifiedDate = myTreeView->myFileSystemModel->index(filePath, lastModifiedColumnIndex);
// this shows the correct row and column for the index, so the index looks correct
qDebug() << "newIndexOfLastModifiedDate: " << newIndexOfLastModifiedDate;
// does not have new value
qDebug() << "newIndexOfLastModifiedDate.data(): " << newIndexOfLastModifiedDate->data();
// has new value
qDebug() << "fileInfo.lastModified(): " << updatedFile->lastModified();
[编辑 - 添加步骤模拟程序流程]
下面我相信是可以模仿的问题的步骤。
重现步骤:
设置一个使用QFileSystemModel作为其模型简单QTreeView则。
设置根路径到一个名为
Root
创建一个文本文件
Test.txt
目录,Root
DIR加载应用程序的内部和它的
Test.txt
文件的最后修改日期在观察Root
dir。保持此应用程序窗口打开。
复制
Test.txt
到不同目录,说Temp
修改该文件并保存在
Temp
复制和更换
Test.txt
覆盖该文件中Root
目录观察最后修改日期在应用程序窗口
结果:最后修改日期不更新
ADDED SAPMLE:
#include <QApplication>
#include <QFileSystemModel>
#include <QFile>
#include <QFileInfo>
#include <QTimer>
#include <QDebug>
#include <QTreeView>
#include <QDateTime>
// Globals
QFileSystemModel *model = NULL;
const QString name = "test.txt";
const int delayOffset = 1000;
// Interface
void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles);
void clean();
void doCreateFile();
void doUpdateFile();
void doTest();
// Implementation
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
int delay = 0;
// Clean
clean();
// Init model
const QString rootPath = QCoreApplication::applicationDirPath();
model = new QFileSystemModel(&a);
model->setRootPath(rootPath);
QObject::connect(model, &QFileSystemModel::dataChanged, &onDataChanged);
// Init file actions
delay += delayOffset * 2;
QTimer tCreate;
tCreate.setSingleShot(true);
tCreate.setInterval(delay);
QObject::connect(&tCreate, &QTimer::timeout, &doCreateFile);
delay += delayOffset * 4;
QTimer tUpdate;
tUpdate.setSingleShot(true);
tUpdate.setInterval(delay);
QObject::connect(&tUpdate, &QTimer::timeout, &doUpdateFile);
// GUI
QTreeView w;
w.setModel(model);
w.setRootIndex(model->index(rootPath));
w.show();
w.expandAll();
qDebug() << "Start";
tCreate.start();
tUpdate.start();
return a.exec();
}
void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
{
qDebug() << "Model changed";
}
void clean()
{
const QString path = QString("%1/%2").arg(QCoreApplication::applicationDirPath()).arg(name);
QFile f(path);
if (f.exists())
f.remove();
}
void doCreateFile()
{
const QString path = QString("%1/%2").arg(QCoreApplication::applicationDirPath()).arg(name);
QFile f(path);
if (!f.open(QIODevice::WriteOnly))
{
qDebug() << "Could not create file";
return ;
}
f.write("Preved");
f.close();
qDebug() << "File created";
doTest();
}
void doUpdateFile()
{
const QString path = QString("%1/%2").arg(QCoreApplication::applicationDirPath()).arg(name);
QFile f(path);
if (!f.open(QIODevice::Append))
{
qDebug() << "Could not open file for modification";
return ;
}
f.write(" medved");
f.close();
qDebug() << "File updated";
doTest();
}
void doTest()
{
const QString path = QString("%1/%2").arg(QCoreApplication::applicationDirPath()).arg(name);
QFileInfo info(path);
qDebug() << "Last modified (real): " << info.lastModified().toString("hh:mm:ss");
qDebug() << "Last modified (model): " << model->lastModified(model->index(path)).toString("hh:mm:ss");
}
您应该使用QFileSystemWatcher
跟踪事件对于每个文件,何时需要更新模型。
QFileSystemWatcher
由于性能问题没有跟踪事件。这是known issue。因此,您可以创建自己的模型和/或使用建议的解决方法:
model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");
谢谢。我不想'重置()',因为它失去了用户扩展节点的状态。我拥有自己的'QFileSystemModel',并将考虑实现'QFileSystemWatcher'。 – GraehamF
我刚刚参加了https://qt-project.org/doc/qt-5.0/qtwidgets/qfilesystemmodel.html - 有一种说法,即QFileSystemModel已经使用QFileSystemWatcher。所以你的promlem在另一个地方。 –
是的,我也了解到。我需要自定义的'QFileSystemModel'来了解文件系统的变化,或者我需要手动更新索引数据。我不知道如何做:/ – GraehamF
'emit myFileTreeView-> dataChanged' What is that ??? –
这是我没有受过教育的尝试,广播说我的自定义'QTreeView'模型中的特定行已经根据网上类似但不同的帖子更改了数据并需要更新。它不符合我的希望。我把它放在那里,所以你可以看到我试过的东西。 – GraehamF
添加代码示例,重现问题。 –