Come aggiornare un QFileSystemModel in un QTreeView dopo che i file sono cambiati attraverso un altro processo?

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

Domanda

Ho un QTreeView con un QFileSystemModel come modello.File e directory vengono caricati correttamente.

Nel flusso di lavoro della mia applicazione, un processo diverso copia e sovrascrive i file nel file system.

Tuttavia, il mio QTreeView non aggiorna la voce/riga per il file sovrascritto (es:la dimensione e i valori lastModified del file non vengono aggiornati ai nuovi valori).

Utilizzando il percorso del file, sono in grado di ottenere un file FileInfo che HA il valore lastModified aggiornato.Tuttavia, utilizzando quello stesso percorso per afferrare il QModelIndex del valore lastModified della riga comporta la restituzione del vecchio valore.

Ho provato alcune cose (vedi sotto) senza alcun risultato.

PER FAVORE, fatemi sapere se siete a conoscenza di come risolvere questo problema.Grazie molto!:)

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

[MODIFICA: aggiunta di passaggi per simulare il flusso di lavoro dell'applicazione]

Credo che i seguenti siano i passaggi che possono simulare il problema.

Passaggi per riprodurre:

  • Imposta un semplice QTreeView che utilizza un QFileSystemModel come modello.

  • Imposta il percorso root su una directory chiamata Root

  • Crea un file di testo, Test.txt all'interno del Root dir

  • Carica l'applicazione e osserva in essa il file Test.txt File Data dell'ultima modifica nel Root dir.

  • Mantieni aperta questa finestra dell'applicazione.

  • copia Test.txt ad a diverso directory, diciamo Temp

  • Modifica il file e salvalo in Temp

  • Copia e Sostituire Test.txt per sovrascrivere il file in Root dir

  • Osservare il Data dell'ultima modifica nella finestra dell'applicazione

Risultato:IL Data dell'ultima modifica non è aggiornato

CAMPIONE AGGIUNTO:

#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" );
}
È stato utile?

Soluzione

Dovresti usare QFileSystemWatcher per tenere traccia degli eventi per ciascun file, quando è necessario aggiornare il modello.

QFileSystemWatcher non tiene traccia degli eventi a causa di problemi di prestazioni.Questo è problema conosciuto.Quindi puoi creare il tuo modello e/o utilizzare la soluzione alternativa proposta:

model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top