分享一下我自己做的QT应用主要功能是实现EXCL-图表转换,这个应用还只是雏形很多功能并没有完成,但是关于界面的功能已经实现了许多,用麻雀虽小五脏俱全来形容挺合适。
感兴趣的可以下载源码:Commits · TTTTHBBBB/Coord (github.com);
1.使用递归和树形结构的方式将文件路径存入树形节点,文件路径作为每个结点的唯一标识,每个目录可能存在多个文件和目录,每个子目录又可能存在多个子节点。
2.使用递归的方式读取树形结构,已经将根目录下的所有文件都读取后,需要将文件再读出来,每个文件就是一个叶子结点,每个目录都是一个节点,跟目录就是根结点。
树形结构:
#ifndef COORDTREENODE_H
#define COORDTREENODE_H
#include <QObject>
#include <QMap>
#include <QList>
#include <QString>
#include <QDebug>
#include "globaldef.hpp"
class CoordTreeNode : public QObject
{
Q_OBJECT
public:
CoordTreeNode(){};
CoordTreeNode(const QString x,const QString y,FILETYPE type):filename(x),filePath(y),isFile(type){};
~CoordTreeNode(){
qDeleteAll(children);
};
void addChild(CoordTreeNode* child) {
children.append(child);
}
CoordTreeNode(const CoordTreeNode& other)
:filename(other.filename),filePath(other.filePath),isFile(other.isFile)
{
for (CoordTreeNode* child : other.children) {
children.append(new CoordTreeNode(*child));
}
}
CoordTreeNode& operator=(const CoordTreeNode& other)
{
if(this == &other)
{
return *this;
}
qDeleteAll(children);
children.clear();
filename = other.filename;
filePath = other.filePath;
isFile = other.isFile;
for (CoordTreeNode* child : other.children)
{
children.append(new CoordTreeNode(*child));
}
return *this;
}
public:
QString filename; // 文件或目录的名称
QString filePath;
FILETYPE isFile; // 标记节点是否为文件
QList<CoordTreeNode*> children; // 子节点列表
};
#endif // COORDTREENODE_H
遍历文件
//递归读取根目录
CoordTreeNode* FileFrame::FileRead(const QString& filepath)
{
QDir dir(filepath);
dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
// QStringList nameFilters;
// nameFilters << "*.xls" << "*.xlsx";
// dir.setNameFilters(nameFilters);
QFileInfoList entries = dir.entryInfoList();
QFileInfo fileInnfo(filepath);
CoordTreeNode* rote = new CoordTreeNode();
rote->filePath = filepath;
rote->filename = fileInnfo.fileName();
rote->isFile = FILETYPE::COORDROTE;
for (const QFileInfo &entry : entries) {
if (entry.isDir())
{//文件夹
CoordTreeNode* childDir = FileRead(entry.absoluteFilePath());
childDir->isFile = FILETYPE::COORDFILE;
rote->addChild(childDir);
}
else if(entry.isFile())
{
CoordTreeNode* childDir = new CoordTreeNode();
childDir->filePath = entry.absoluteFilePath();
childDir->filename = entry.fileName();
childDir->isFile = FILETYPE::COORDTEXT;
rote->addChild(childDir);
}
}
return rote;
}
void FileFrame::slot_FileOpen()
{
fileName = QFileDialog::getExistingDirectory(this,"Coord Select","",QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(fileName.isEmpty())
{
emit signal_FlickWindow(tr("File_open_failure"),FLICKTYPE::FAILD);
return;
}
CoordRoot = FileRead(fileName);
ui->frameobject->ClearTree();
ui->frameobject->ReadTreeNode(*CoordRoot);
}
读取文件和添加QTreeWidgetItem
QTreeWidgetItem* CoordTreeWidget::addTreeItem(QTreeWidgetItem *parentItem,QString name,FILETYPE TYPE)
{
if(name.isEmpty() || parentItem == nullptr) return nullptr;
QTreeWidgetItem *item = new QTreeWidgetItem();
if(TYPE == FILETYPE::COORDFILE)
{
item->setIcon(0,QIcon(ClosePath));
item->setText(0,name);
item->setBackground(0,NormalColor);
}
else if(TYPE == FILETYPE::COORDTEXT)
{
item->setIcon(0,QIcon(TextPath));
item->setText(0,name);
item->setBackground(0,NormalColor);
}
parentItem->addChild(item);
listItem.append(item);
textList.append({name,TYPE});
return item;
}
void CoordTreeWidget::ReadTreeNode(const CoordTreeNode& rote,QTreeWidgetItem *parentItem)
{//层节点都是目录
if(rote.isFile == FILETYPE::COORDROTE)
{//根节点
topItem->setText(0,rote.filename);
this->addTopLevelItem(topItem);
parentItem = topItem;
}else if(rote.isFile == FILETYPE::COORDFILE)
{//子目录节点
parentItem = addTreeItem(parentItem,rote.filename,rote.isFile);
}
if(parentItem == nullptr) return ;
DateBase[parentItem] = rote;
for(auto node = rote.children.constBegin(); node != rote.children.constEnd(); node++)
{
CoordTreeNode* childNode = *node;
if(childNode->isFile == FILETYPE::COORDFILE)
{
ReadTreeNode(*childNode,parentItem);
}else if(childNode->isFile == FILETYPE::COORDTEXT)
{
QTreeWidgetItem *Childitem = addTreeItem(parentItem,childNode->filename,childNode->isFile);
DateBase[Childitem] = *childNode;
}
}
}