Reputation: 77
I have a simple QTreeWidget
pointing to the root directory:
#include <QTreeWidget>
#include <QStringList>
#include <QApplication>
int main(int argc, char **argv)
{
QApplication application(argc, argv);
QStringList fileNames{"TEST/branch", "trunk"};
QTreeWidget treeWidget;
treeWidget.setColumnCount(1);
for (const auto& filename : fileNames)
{
QTreeWidgetItem *parentTreeItem = new QTreeWidgetItem(&treeWidget);
parentTreeItem->setText(0, filename.split('/').first());
QStringList filenameParts = filename.split('/').mid(1);
for(const auto& filenamePart : filenameParts)
{
QTreeWidgetItem *treeItem = new QTreeWidgetItem();
treeItem->setText(0, filenamePart);
parentTreeItem->addChild(treeItem);
parentTreeItem = treeItem;
}
}
treeWidget.show();
return application.exec();
}
Output:
The item I have selected above is /TEST/branches. How can I get the absolute path of the currently selected item?
Upvotes: 4
Views: 1589
Reputation: 1490
Well, I don't think there is a built in function does that but you can write a function yourself like
QString treeItemToFullPath(QTreeWidgetItem* treeItem)
{
QString fullPath= treeItem->text(0);
while (treeItem->parent() != NULL)
{
fullPath= treeItem->parent()->text(0) + "/" + fullPath;
treeItem = treeItem->parent();
}
return fullPath;
}
edit: Input treeItem is the selected tree item that you want to show its path. if you are sure at least one item is selected, you can get it by
treeWidget.selectedItems().first();
Another mehtod is using tooltips. You can add tip for each item, while you are adding them to tree, but you can do this after you add them in their final place.
change this
for(const auto& filenamePart : filenameParts)
{
QTreeWidgetItem *treeItem = new QTreeWidgetItem();
treeItem->setText(0, filenamePart);
parentTreeItem->addChild(treeItem);
parentTreeItem = treeItem;
}
as this
for(const auto& filenamePart : filenameParts)
{
QTreeWidgetItem *treeItem = new QTreeWidgetItem();
treeItem->setText(0, filenamePart);
parentTreeItem->addChild(treeItem);
parentTreeItem = treeItem;
treeItem->setToolTip(0, treeItemToFullPath(treeItem));
}
this way you will see the full path whenever you hover the mouse on the item.
Upvotes: 3
Reputation: 98505
To get notified of the current item change, one can use QTreeWidget::currentItemChanged
or QItemSelectionModel::currentChanged
.
There are two main approaches to obtaining the full path:
Iterate up the tree from the selected item and reconstruct the path. This keeps the data model normalized - without redundant information.
Store full path to each item.
If the tree is large, storing the model normalized will use less memory. Given that selection of the items is presumably rare because it's done on explicit user input, the cost of iterating the tree to extract the full path is minuscule. Humans aren't all that fast when it comes to mashing the keys or the mouse button.
The example demonstrates both approaches:
// https://github.com/KubaO/stackoverflown/tree/master/questions/tree-path-41037995
#include <QtWidgets>
QTreeWidgetItem *get(QTreeWidgetItem *parent, const QString &text) {
for (int i = 0; i < parent->childCount(); ++i) {
auto child = parent->child(i);
if (child->text(0) == text)
return child;
}
return new QTreeWidgetItem(parent, {text});
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QStringList filenames{"TEST/branch", "TEST/foo", "trunk"};
QWidget window;
QVBoxLayout layout(&window);
QTreeWidget treeWidget;
QLabel label1, label2;
for (const auto &filename : filenames) {
QString path;
auto item = treeWidget.invisibleRootItem();
for (auto const &chunk : filename.split('/')) {
item = get(item, chunk);
path.append(QStringLiteral("/%1").arg(chunk));
item->setData(0, Qt::UserRole, path);
}
}
QObject::connect(&treeWidget, &QTreeWidget::currentItemChanged, [&](const QTreeWidgetItem *item){
QString path;
for (; item; item = item->parent())
path.prepend(QStringLiteral("/%1").arg(item->text(0)));
label1.setText(path);
});
QObject::connect(&treeWidget, &QTreeWidget::currentItemChanged, [&](const QTreeWidgetItem *item){
label2.setText(item->data(0, Qt::UserRole).toString());
});
layout.addWidget(&treeWidget);
layout.addWidget(&label1);
layout.addWidget(&label2);
window.show();
return app.exec();
}
Upvotes: 2