0

Sometimes I need to backup file, If the size of all the files in a certain directory is too large, it would take a considerable amount of time to back up all the files in this directory every time., so I found how-can-i-check-if-the-content-of-a-folder-was-changed and What is the fastest way to check if something changed in a folder is similar to my needs. I see someone suggest use FileSystemWatcher, but it seems that need to run background, so it does not seem like a good option.

So I want to use Qt(version 6.5.1) to write a application that can find directory and file changed in a period of time for display use Qt GUI.

I found make-tree-folder-from-qtreeview-or-qtreewidget seems to meet my needs, but it run as a exe application, and original code can't run at Qt(version 6.5.1), I just change

appendToModel(&model, name.split("/", QString::SkipEmptyParts), size);

to

appendToModel(&model, name.split("/", Qt::SkipEmptyParts), size);

So it changed to like this:

#include <QApplication>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QStandardItemModel>
#include <QTreeView>
#include <QFileIconProvider>



QStandardItem * findChilItem(QStandardItem *it, const QString & text){
    if(!it->hasChildren())
        return nullptr;
    for(int i=0; i< it->rowCount(); i++){
        if(it->child(i)->text() == text)
            return it->child(i);
    }
    return nullptr;
}

static void appendToModel(QStandardItemModel *model, const QStringList & list, const QString & size){
    QStandardItem *parent = model->invisibleRootItem();
    QFileIconProvider provider;

    for(QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
    {
        QStandardItem *item = findChilItem(parent, *it);
        if(item){
            parent = item;
            continue;
        }
        item = new QStandardItem(*it);
        if(std::next(it) == list.end()){
            item->setIcon(provider.icon(QFileIconProvider::File));
            parent->appendRow({item, new QStandardItem(size)});
        }
        else{
            item->setIcon(provider.icon(QFileIconProvider::Folder));
            parent->appendRow(item);
        }
        parent = item;
    }
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QStandardItemModel model;
    model.setHorizontalHeaderLabels({"Name", "Size"});
    const std::string json = R"([
                             {"name": "/folder1/file1.txt";"size": "1KB"},
                             {"name": "/folder1/file2.txt";"size": "1KB"},
                             {"name": "/folder1/sub/file3.txt";"size": "1KB"},
                             {"name": "/folder2/file4.txt";"size": "1KB"},
                             {"name": "/folder2/file5.txt";"size": "1KB"}
                             ])";

    QJsonParseError parse;
    // The string is not a valid json, the separator must be a comma
    // and not a semicolon, which is why it is being replaced
    QByteArray data = QByteArray::fromStdString(json).replace(";", ",");
    QJsonDocument const& jdoc =  QJsonDocument::fromJson(data, &parse);
    Q_ASSERT(parse.error == QJsonParseError::NoError);
    if(jdoc.isArray()){
        for(const QJsonValue &element : jdoc.array() ){
            QJsonObject obj = element.toObject();
            QString name = obj["name"].toString();
            QString size = obj["size"].toString();
            appendToModel(&model, name.split("/", Qt::SkipEmptyParts), size);
        }
    }

    QTreeView view;
    view.setModel(&model);
    view.show();
    return a.exec();
}

Now it can run at my computer:

enter image description here

But when I add above code to my code, I get error:

enter image description here

I don't know how to solve this problem and this error seems to don't give me more error details.

But when I comment below line, program can be compiled.

appendToModel(&model, name.split("/", Qt::SkipEmptyParts), size);

Now it can be compiled, but can't correct display tree folder at QTreeview (If there are other controls that can solve the problem, they can also be used.) see below picture:

enter image description here

I expect that QTreeview of "Before" below can display correct like QTreeview of "Now" below or like above application(application named: TestTreeView) run result.

How could I solve this problem? Thank you.

Tom
  • 417
  • 3
  • 10

1 Answers1

1

I solved this problem by myself; now it can correctly display as I expect.

I changed findChilItem to MyWidget::findChilItem and changed appendToModel to MyWidget::appendToModel to solve the link error. The answer on “make-tree-folder-from-qtreeview-or-qtreewidget“ is very useful for displaying a tree folder, but I needed to modify it to suit my needs; see more detail at my code on Github.

I hope I can use Qt to write an application for other people to use that can find directories and files changed without running a background service, like FileSystemWatcher, in a period of time for displaying use of the Qt GUI.

enter image description here

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Tom
  • 417
  • 3
  • 10