Como atualizar um QFileSystemModel em um QTreeView após a alteração dos arquivos por meio de outro processo?
-
24-12-2019 - |
Pergunta
eu tenho um QTreeView
com um QFileSystemModel
como o modelo.Arquivos e diretórios são carregados corretamente.
No fluxo de trabalho do meu aplicativo, um processo diferente copia e sobrescreve arquivos no sistema de arquivos.
No entanto, meu QTreeView
não atualiza o item/linha do arquivo substituído (por exemplo:os valores size e lastModified do arquivo não são atualizados para os novos valores).
Usando o caminho do arquivo, consigo obter um FileInfo
que TEM o valor lastModified atualizado.No entanto, usando isso mesmo caminho para pegar o QModelIndex
do valor lastModified da linha resulta no retorno do valor antigo.
Eu tentei algumas coisas (veja abaixo) sem sucesso.
POR FAVOR, deixe-me saber se você sabe como resolver isso.Muito obrigado!:)
// ... 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();
[EDITAR - adicionando etapas para simular o fluxo de trabalho do aplicativo]
Acredito que a seguir sejam as etapas que podem imitar o problema.
Passos para reproduzir:
Configure um QTreeView simples que usa um QFileSystemModel como modelo.
Defina o caminho raiz para um diretório chamado
Root
Crie um arquivo de texto,
Test.txt
dentro doRoot
diretórioCarregue o aplicativo e observe nele o
Test.txt
arquivos Data da última modificação noRoot
dir.Mantenha esta janela do aplicativo aberta.
cópia de
Test.txt
para um diferente diretório, digamosTemp
Modifique o arquivo e salve em
Temp
Copiar e Substituir
Test.txt
para sobrescrever o arquivo emRoot
diretórioObserve o Data da última modificação na janela do aplicativo
Resultado:O Data da última modificação não está atualizado
SAPMLE ADICIONADO:
#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" );
}
Solução
Você deveria usar QFileSystemWatcher
para rastrear eventos de cada arquivo, quando for necessário atualizar seu modelo.
QFileSystemWatcher
não rastreia eventos devido a problemas de desempenho.Isso é problema conhecido.Portanto, você pode criar seu próprio modelo e/ou usar a solução alternativa proposta:
model.setRootPath("");
model.setRootPath("the_folder_you_want_to_update");