別のプロセスを通じてファイルが変更された後、QTreeView で QFileSystemModel を更新するにはどうすればよいですか?

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

質問

私は持っています 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 ディレクトリ

  • 観察してください 最終更新日 アプリケーションウィンドウで

結果:の 最終更新日 更新されていない

追加された樹木:

#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" );
}
役に立ちましたか?

解決

使用する必要があります QFileSystemWatcher モデルを更新する必要がある場合に、各ファイルのイベントを追跡します。

QFileSystemWatcher パフォーマンスの問題のため、イベントは追跡されません。これは 既知の問題. 。したがって、独自のモデルを作成したり、提案された回避策を使用したりできます。

model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top