2

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

在我的应用程序工作流程中,不同的进程复制并覆盖文件系统上的文件。

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

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

我尝试了一些事情(见下文)无济于事。

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

// ... 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

  • 加载应用程序并在其中观察目录中文件Test.txt上次修改日期Root

  • 保持此应用程序窗口打开。

  • 复制Test.txt不同的目录,比如说Temp

  • 修改文件并保存在Temp

  • 复制并替换 Test.txt以覆盖Root目录中的文件

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

结果:上次修改日期未更新

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

1 回答 1

3

QFileSystemWatcher当需要更新模型时,您应该使用它来跟踪每个文件的事件。

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

model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");
于 2014-02-28T13:21:44.003 回答