Сделать папку из дерева из QTreeView или QTreeWidget - PullRequest
0 голосов
/ 25 апреля 2018

прочитать дерево папок из Rest API, а затем показать их пользователю

Пример ответа json после вызова API:

[
{"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"}
]

Я только хочу сделать GUI как на картинке ниже: enter image description here

Есть 2 варианта :

  1. QTreeView

  2. QTreeWidget

На этой фотографии я использовал QTreeWidget (со статическими данными). В настоящее время я не знаю, как сделать модель данных для этого.

Я сделал TreeModel, чтобы установить данные для QtreeView. Но когда они отображаются в графическом интерфейсе, все данные отображаются только в столбце Имя. Я скопировал код с http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

Но сейчас я не могу решить эту проблему. Мне нужен пример исходного кода для этого. Кроме того, я просто хочу показать только дерево.

не используйте QFileSystem, потому что данные поступают из Rest API.

1 Ответ

0 голосов
/ 26 апреля 2018

Что вам нужно сделать, это проанализировать json, получив имя файла и размер, затем разделить имя с помощью «/» и добавить его в модель соответствующим образом.

#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("/", QString::SkipEmptyParts), size);
        }
    }

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

Примечание: точка с запятой не является допустимым разделителем для json, поэтому мне пришлось изменить его.

enter image description here

...