文件通过另一个过程更改后,如何在QTreeView中刷新QFileSystemModel? [英] How to refresh a QFileSystemModel in a QTreeView after files change through another process?

查看:974
本文介绍了文件通过另一个过程更改后,如何在QTreeView中刷新QFileSystemModel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以QFileSystemModel为模型的QTreeView.文件和目录正确加载.

I have a QTreeView with a QFileSystemModel as the model. Files and directories load correctly.

在我的应用程序工作流程中,另一个进程复制并覆盖文件系统上的文件.

In my application workflow, a different process copies and overwrites files on the file system.

但是,我的QTreeView不会更新被覆盖文件的项目/行(例如:文件的大小和lastModified值不会更新为新值).

However, my QTreeView does not update the item/row for the overwritten file (eg: the size and lastModified values for the file do not update to the new values).

使用文件路径,我可以得到一个FileInfo确实具有更新的lastModified值.但是,使用该相同路径来获取该行的lastModified值的QModelIndex会导致该行返回旧值.

Using the file path, I'm able to get a FileInfo that DOES have the updated lastModified value. However, using that same path to grab the QModelIndex of the row's lastModified value results in it returning the old value.

我尝试了几件事(见下文),无济于事.

I've tried a few things (see below) to no avail.

如果您知道如何解决此问题,请告诉我.非常感谢! :)

PLEASE let me know if you are aware of how to resolve this. Many Thanks! :)

// ... 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();

我认为以下是可以模拟该问题的步骤.

The following I believe to be the steps that can mimic the issue.

复制步骤:

  • 设置一个使用QFileSystemModel作为其模型的简单QTreeView.

  • Setup a simple QTreeView that uses a QFileSystemModel as its model.

将根路径设置为名为Root

Root目录

加载应用程序,并在其中观察Root目录中Test.txt文件的最后修改日期.

Load the application and observe in it the Test.txt file's Last Modified Date in the Root dir.

打开此应用程序窗口.

Test.txt复制到不同的目录,例如Temp

修改文件并保存在Temp

复制并替换 Test.txt以覆盖Root目录

在应用程序窗口中观察最后修改日期

Observe the Last Modified Date in the application window

结果:最后修改日期未更新

添加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" );
}

推荐答案

您应使用

You should use QFileSystemWatcher to track events for each file, when it necessary to update your model.

QFileSystemWatcher不跟踪事件.这是已知问题.因此,您可以创建自己的模型和/或使用建议的解决方法:

QFileSystemWatcher does not track an events because of performance issues. This is known issue. So you may create your own model and/or use proposed workaround:

model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");

这篇关于文件通过另一个过程更改后,如何在QTreeView中刷新QFileSystemModel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆