I have a file which has absolute filepaths listed, 1 per line. The listed files are in order, so all files in e.g. the /Documents/
dir will be listed after eachother in the file.
What I want to do is to place all these files in a QTreeWidget
in a nice hierarchic structure, just like a normal filesystem. How would I do that from my file of absolute paths I have?
This is how far I've gotten with my coding on this:
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();
This works fine, but it only lists all the filenames after eachother. I guess I have to do some recursive function but recursion is not my best friend, I prefer iteration! Could someone give me a push in the right direction? :)
No recursion should be necessary. You can use QString::split()
to split the file path into separate QStrings in a QStringList based on a separator (i.e., "/"), then iterate through each QString to determine the file structure.
EDIT: Here is an example:
#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();
}
Note that you can use QTreeWidgetItem::setData()
to set the file name for each file if you like. My example does not do that, though.