如何从文件路径的 QStringList 制作 QStandardItemModel
How to make a QStandardItemModel from QStringList of file paths
我是 C++ 和 Qt 的新手,似乎找不到合适的解决方案。我想使用 QStandardItemModel 创建一个 QTreeView。我有一个 file/folder 路径列表(在 QStringList 中),其结构格式如下:
Arena/Main/00078/a.txt
Arena/Main/00080/b.txt
Arena/Main/00080/collision/c.txt
Arena/Main/00080/light/d.txt
Arena/Main/00081/e.txt
Characters/f.txt
Characters/Main/g.txt
Characters/Main/someFolder/h.txt
我以前使用 QFileSystemModel 并制作了实际的临时目录,作为解决方法遍历列表:
QDir dir(temp_path);
if (!dir.exists(dir_string)){
dir.mkpath(dir_string);
}
QFile file(filepath_str);
file.open(QIODevice::WriteOnly);
这给了我这样的工作结果:https://i.stack.imgur.com/ITzJz.png
但是,该列表最多可以包含 10,000 多个文件,这使得它成为一个更长的向后解决方法。我想使用从路径列表创建的 QStandardItemModel 以类似的方式填充 QTreeView。
您可以像这样将创建的路径存储在地图中:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMap>
#include <QStandardItemModel>
class QStandardItem;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
void addPathRecusively(const QStringList &path_parts, QStandardItem *parent, int layer = 1);
QMap<QString, QStandardItem*> path_item_map_;
QStandardItemModel model_;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QStringList>
#include <QTreeView>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QStringList filenames =
{
"Arena/Main/00078/a1.txt",
"Arena/Main/00078/a2.txt",
"Arena/Main/00080/b.txt",
"Arena/Main/00080/collision/c.txt",
"Arena/Main/00080/light/d.txt",
"Arena/Main/00081/e1.txt",
"Arena/Main/00081/e2.txt",
"Arena/Main/00081/e3.txt",
"Characters/f.txt",
"Characters/Main/g.txt",
"Characters/Main/someFolder/h.txt",
};
for (auto &filename : filenames)
{
QStringList parts = filename.split("/");
parts.pop_back();
addPathRecusively(parts, model_.invisibleRootItem());
}
QTreeView *view = new QTreeView{this};
view->setModel(&model_);
this->setCentralWidget(view);
this->resize(500, 500);
}
MainWindow::~MainWindow()
{
}
void MainWindow::addPathRecusively(const QStringList &path_parts, QStandardItem *parent, int layer)
{
QStringList path_parts_to_layer;
std::copy(path_parts.begin(), path_parts.begin() + layer, std::back_inserter(path_parts_to_layer));
QString path = path_parts_to_layer.join("/");
auto item = path_item_map_.value(path);
if (item == nullptr)
{
item = new QStandardItem{path_parts_to_layer.last()};
path_item_map_.insert(path, item);
parent->appendRow({item, new QStandardItem});
}
if (path_parts.length() == layer)
{
auto file_count_index = model_.indexFromItem(item).siblingAtColumn(1);
model_.setData(file_count_index, file_count_index.data().toInt() + 1, Qt::DisplayRole);
}
else
addPathRecusively(path_parts, item, layer + 1);
}
我是 C++ 和 Qt 的新手,似乎找不到合适的解决方案。我想使用 QStandardItemModel 创建一个 QTreeView。我有一个 file/folder 路径列表(在 QStringList 中),其结构格式如下:
Arena/Main/00078/a.txt
Arena/Main/00080/b.txt
Arena/Main/00080/collision/c.txt
Arena/Main/00080/light/d.txt
Arena/Main/00081/e.txt
Characters/f.txt
Characters/Main/g.txt
Characters/Main/someFolder/h.txt
我以前使用 QFileSystemModel 并制作了实际的临时目录,作为解决方法遍历列表:
QDir dir(temp_path);
if (!dir.exists(dir_string)){
dir.mkpath(dir_string);
}
QFile file(filepath_str);
file.open(QIODevice::WriteOnly);
这给了我这样的工作结果:https://i.stack.imgur.com/ITzJz.png
但是,该列表最多可以包含 10,000 多个文件,这使得它成为一个更长的向后解决方法。我想使用从路径列表创建的 QStandardItemModel 以类似的方式填充 QTreeView。
您可以像这样将创建的路径存储在地图中:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMap>
#include <QStandardItemModel>
class QStandardItem;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
void addPathRecusively(const QStringList &path_parts, QStandardItem *parent, int layer = 1);
QMap<QString, QStandardItem*> path_item_map_;
QStandardItemModel model_;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QStringList>
#include <QTreeView>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QStringList filenames =
{
"Arena/Main/00078/a1.txt",
"Arena/Main/00078/a2.txt",
"Arena/Main/00080/b.txt",
"Arena/Main/00080/collision/c.txt",
"Arena/Main/00080/light/d.txt",
"Arena/Main/00081/e1.txt",
"Arena/Main/00081/e2.txt",
"Arena/Main/00081/e3.txt",
"Characters/f.txt",
"Characters/Main/g.txt",
"Characters/Main/someFolder/h.txt",
};
for (auto &filename : filenames)
{
QStringList parts = filename.split("/");
parts.pop_back();
addPathRecusively(parts, model_.invisibleRootItem());
}
QTreeView *view = new QTreeView{this};
view->setModel(&model_);
this->setCentralWidget(view);
this->resize(500, 500);
}
MainWindow::~MainWindow()
{
}
void MainWindow::addPathRecusively(const QStringList &path_parts, QStandardItem *parent, int layer)
{
QStringList path_parts_to_layer;
std::copy(path_parts.begin(), path_parts.begin() + layer, std::back_inserter(path_parts_to_layer));
QString path = path_parts_to_layer.join("/");
auto item = path_item_map_.value(path);
if (item == nullptr)
{
item = new QStandardItem{path_parts_to_layer.last()};
path_item_map_.insert(path, item);
parent->appendRow({item, new QStandardItem});
}
if (path_parts.length() == layer)
{
auto file_count_index = model_.indexFromItem(item).siblingAtColumn(1);
model_.setData(file_count_index, file_count_index.data().toInt() + 1, Qt::DisplayRole);
}
else
addPathRecusively(path_parts, item, layer + 1);
}