Wie aktualisiere ich ein QFileSystemModel in einem QTreeView, nachdem sich Dateien durch einen anderen Prozess geändert haben?

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

Frage

Ich habe ein QTreeView mit einem QFileSystemModel als Vorbild.Dateien und Verzeichnisse werden korrekt geladen.

In meinem Anwendungsworkflow kopiert und überschreibt ein anderer Prozess Dateien im Dateisystem.

Allerdings mein QTreeView aktualisiert das Element/die Zeile für die überschriebene Datei nicht (z. B.:Die Werte „size“ und „lastModified“ für die Datei werden nicht auf die neuen Werte aktualisiert.

Mithilfe des Dateipfads kann ich eine erhalten FileInfo das hat den aktualisierten lastModified-Wert.Allerdings nutzen wir das gleichen Weg um das zu ergreifen QModelIndex des lastModified-Werts der Zeile führt dazu, dass der alte Wert zurückgegeben wird.

Ich habe ein paar Dinge ausprobiert (siehe unten), ohne Erfolg.

BITTE teilen Sie mir mit, ob Sie wissen, wie Sie das Problem beheben können.Vielen Dank!:) :)

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

[BEARBEITEN – Schritte zur Simulation des Anwendungsworkflows hinzufügen]

Ich glaube, dass die folgenden Schritte das Problem nachahmen können.

Schritte zum Reproduzieren:

  • Richten Sie eine einfache QTreeView ein, die ein QFileSystemModel als Modell verwendet.

  • Legen Sie den Root-Pfad auf ein Verzeichnis mit dem Namen fest Root

  • Erstellen Sie eine Textdatei, Test.txt innerhalb der Root dir

  • Laden Sie die Anwendung und beobachten Sie darin die Test.txt Dateien Zuletzt geändertes Datum im Root dir.

  • Lassen Sie dieses Anwendungsfenster geöffnet.

  • Kopieren Test.txt zu einem anders Verzeichnis, sagen wir Temp

  • Ändern Sie die Datei und speichern Sie sie unter Temp

  • Kopieren und Ersetzen Test.txt um die Datei zu überschreiben Root dir

  • Beobachte Zuletzt geändertes Datum im Anwendungsfenster

Ergebnis:Der Zuletzt geändertes Datum wird nicht aktualisiert

HINZUGEFÜGTES 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" );
}
War es hilfreich?

Lösung

Du solltest benutzen QFileSystemWatcher um Ereignisse für jede Datei zu verfolgen, wenn eine Aktualisierung Ihres Modells erforderlich ist.

QFileSystemWatcher verfolgt aufgrund von Leistungsproblemen keine Ereignisse.Das ist bekanntes Problem.Sie können also Ihr eigenes Modell erstellen und/oder die vorgeschlagene Problemumgehung verwenden:

model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top