Comment actualiser un QFileSystemModel dans un QTreeView après la modification des fichiers via un autre processus ?

StackOverflow https://stackoverflow.com//questions/22083933

Question

j'ai un QTreeView avec un QFileSystemModel comme modèle.Les fichiers et répertoires se chargent correctement.

Dans le flux de travail de mon application, un processus différent copie et écrase les fichiers sur le système de fichiers.

Cependant, mon QTreeView ne met pas à jour l'élément/la ligne du fichier écrasé (par exemple :les valeurs size et lastModified du fichier ne sont pas mises à jour avec les nouvelles valeurs).

En utilisant le chemin du fichier, je peux obtenir un FileInfo qui a la valeur lastModified mise à jour.Cependant, en utilisant cela même chemin pour saisir le QModelIndex de la valeur lastModified de la ligne entraîne le retour de l'ancienne valeur.

J'ai essayé quelques choses (voir ci-dessous) en vain.

VEUILLEZ me faire savoir si vous savez comment résoudre ce problème.Merci beaucoup!:)

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

[EDIT - ajout d'étapes pour simuler le flux de travail de l'application]

Je pense que ce qui suit sont les étapes qui peuvent imiter le problème.

Étapes pour reproduire :

  • Configurez un simple QTreeView qui utilise un QFileSystemModel comme modèle.

  • Définissez le chemin racine sur un répertoire appelé Root

  • Créez un fichier texte, Test.txt à l'intérieur du Root dir

  • Chargez l'application et observez-y les Test.txt des dossiers Date de la dernière modification dans le Root dir.

  • Gardez cette fenêtre d'application ouverte.

  • Copie Test.txt à un différent répertoire, disons Temp

  • Modifiez le fichier et enregistrez-le dans Temp

  • Copiez et Remplacer Test.txt pour écraser le fichier dans Root dir

  • Observer l Date de la dernière modification dans la fenêtre de l'application

Résultat:Le Date de la dernière modification n'est pas mis à jour

SAPMLE AJOUTÉ :

#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" );
}
Était-ce utile?

La solution

Tu devrais utiliser QFileSystemWatcher pour suivre les événements pour chaque fichier, lorsqu'il est nécessaire de mettre à jour votre modèle.

QFileSystemWatcher ne suit pas les événements en raison de problèmes de performances.C'est problème connu.Vous pouvez donc créer votre propre modèle et/ou utiliser la solution de contournement proposée :

model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top