从 QTreeView 或 QTreeWidget 创建树文件夹
Make tree folder from QTreeView or QTreeWidget
从 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:
有2个选项:
QTreeView
QTreeWidget
在这张照片中,我使用了 QTreeWidget(带有静态数据)。
目前,我不知道为此制作数据模型。
我制作了 TreeModel 来为 QtreeView 设置数据。
但是当它们显示在 GUI 中时,所有数据仅显示在名称列中。
我从 http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
复制了代码
但是现在我无法解决这个问题。为此,我需要一个示例源代码。
另外,我也只想简单地显示一个树视图。
不要使用 QFileSystem,因为数据来自 Rest API。
你要做的是通过获取文件名和大小来解析 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 的有效分隔符,所以我不得不更改它。
从 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:
有2个选项:
QTreeView
QTreeWidget
在这张照片中,我使用了 QTreeWidget(带有静态数据)。 目前,我不知道为此制作数据模型。
我制作了 TreeModel 来为 QtreeView 设置数据。 但是当它们显示在 GUI 中时,所有数据仅显示在名称列中。 我从 http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
复制了代码但是现在我无法解决这个问题。为此,我需要一个示例源代码。 另外,我也只想简单地显示一个树视图。
不要使用 QFileSystem,因为数据来自 Rest API。
你要做的是通过获取文件名和大小来解析 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 的有效分隔符,所以我不得不更改它。