كيفية تحديث QFileSystemModel في QTreeView بعد تغيير الملفات من خلال عملية أخرى؟

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

[تحرير - إضافة خطوات لمحاكاة سير عمل التطبيق]

أعتقد أن ما يلي هو الخطوات التي يمكن أن تحاكي المشكلة.

خطوات التكاثر:

  • قم بإعداد QTreeView بسيط يستخدم QFileSystemModel كنموذج له.

  • قم بتعيين مسار الجذر إلى دليل يسمى 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