我有一个文件,列出了绝对文件路径,每行1个。列出的文件是有序的,因此所有文件都在例如/Documents/
目录将在文件中彼此之后列出。
我想要做的是将所有这些文件放在一个漂亮的分层结构中的QTreeWidget
中,就像普通的文件系统一样。我如何从我的绝对路径文件中做到这一点?
这就是我对此进行编码的程度:
QFile file(FILENAME_ENCRYPTED);
QString line;
QDir dir;
QTreeWidgetItem *item;
if (file.open(QIODevice::ReadOnly)) {
QTextStream stream( &file );
do {
line = stream.readLine();
if (!line.isNull()) {
dir = QDir(line);
item = new QTreeWidgetItem();
item->setText(0, dir.dirName());
this->ui->treeWidget->addTopLevelItem(item);
}
} while (!line.isNull());
}
file.close();
这很好用,但它只列出了彼此之后的所有文件名。我想我必须做一些递归函数,但递归不是我最好的朋友,我更喜欢迭代!有人能给我一个正确的方向吗? :)
答案 0 :(得分:9)
不需要递归。您可以使用QString::split()
将文件路径拆分为基于分隔符(即“/”)的QStringList中的单独QStrings,然后遍历每个QString以确定文件结构。
编辑:这是一个例子:
#include <QtGui>
const QString s1 = "Docs/Testing/textFile1.txt";
const QString s2 = "Docs/Testing/textFile2.txt";
const QString s3 = "Docs/Testing/textFile3.txt";
const QString s4 = "Docs/Testing/AnotherFolder/textFile4.txt";
const QString s5 = "ThisIsGonnaBeCrazy/WholeNewFolder/AndAnother/file.pdf";
const QString s6 = "ThisIsGonnaBeCrazy/file.doc";
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
QTreeWidget *treeWidget = new QTreeWidget;
QStringList fileNames;
fileNames << s1 << s2 << s3 << s4 << s5 << s6;
QTreeWidgetItem *topLevelItem = NULL;
foreach (const QString &fileName, fileNames)
{
QStringList splitFileName = fileName.split("/");
// add root folder as top level item if treeWidget doesn't already have it
if (treeWidget->findItems(splitFileName[0], Qt::MatchFixedString).isEmpty())
{
topLevelItem = new QTreeWidgetItem;
topLevelItem->setText(0, splitFileName[0]);
treeWidget->addTopLevelItem(topLevelItem);
}
QTreeWidgetItem *parentItem = topLevelItem;
// iterate through non-root directories (file name comes after)
for (int i = 1; i < splitFileName.size() - 1; ++i)
{
// iterate through children of parentItem to see if this directory exists
bool thisDirectoryExists = false;
for (int j = 0; j < parentItem->childCount(); ++j)
{
if (splitFileName[i] == parentItem->child(j)->text(0))
{
thisDirectoryExists = true;
parentItem = parentItem->child(j);
break;
}
}
if (!thisDirectoryExists)
{
parentItem = new QTreeWidgetItem(parentItem);
parentItem->setText(0, splitFileName[i]);
}
}
QTreeWidgetItem *childItem = new QTreeWidgetItem(parentItem);
childItem->setText(0, splitFileName.last());
}
setCentralWidget(treeWidget);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
请注意,如果您愿意,可以使用QTreeWidgetItem::setData()
为每个文件设置文件名。不过,我的例子并没有这样做。
答案 1 :(得分:1)
这对我有用:
QStringList tokens = path.split ( '/' );
QTreeWidgetItem* treeWidgetItem = NULL;
for ( int32_t j = 0 ; j < packageTreeWidget->topLevelItemCount(); ++j )
{
if ( packageTreeWidget->topLevelItem ( j )->text ( 0 ) == tokens.at ( 0 ) )
{
treeWidgetItem = packageTreeWidget->topLevelItem ( j );
break;
}
}
if ( treeWidgetItem == NULL )
{
treeWidgetItem = new QTreeWidgetItem;
treeWidgetItem->setText ( 0, tokens.at ( 0 ) );
packageTreeWidget->addTopLevelItem ( treeWidgetItem );
}
for ( int32_t j = 1; j < tokens.size(); ++j )
{
int32_t k;
for ( k = 0 ; k < treeWidgetItem->childCount(); ++k )
{
if ( treeWidgetItem->child ( k )->text ( 0 ) == tokens.at ( j ) )
{
treeWidgetItem = treeWidgetItem->child ( k );
break;
}
}
if ( k == treeWidgetItem->childCount() )
{
QTreeWidgetItem* newTreeWidgetItem = new QTreeWidgetItem;
newTreeWidgetItem->setText ( 0, tokens.at ( j ) );
treeWidgetItem->addChild ( newTreeWidgetItem );
treeWidgetItem = newTreeWidgetItem;
}
}
指数&#39; i&#39;在循环中缺少,因为我用来迭代文件路径,替换&#39; packageTreeWidget&#39;使用Tree Widget的名称,我使用它来显示类似zip的包文件的内容。