如何在鼠标单击的QTreeWidget中获取当前所选项目的绝对路径

时间:2016-12-08 11:08:28

标签: c++ qt qt4 qtreewidget

我有一个简单的QTreeWidget指向根目录:

#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();
}

输出:

enter image description here

我上面选择的项目是/ TEST / branches。如何获取当前所选项目的绝对路径?

2 个答案:

答案 0 :(得分:2)

要获得当前项目更改的通知,可以使用QTreeWidget::currentItemChangedQItemSelectionModel::currentChanged

获得完整路径有两种主要方法:

  1. 从所选项目中迭代树并重建路径。这样可以使数据模型标准化 - 无需冗余信息。

  2. 存储每个项目的完整路径。

  3. 如果树很大,存储标准化的模型将使用更少的内存。鉴于项目的选择可能很少,因为它是在显式用户输入上完成的,因此迭代树以提取完整路径的成本是微不足道的。在混搭键或鼠标键时,人类并不是那么快。

    该示例演示了两种方法:

    // 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();
    }
    

答案 1 :(得分:1)

好吧,我不认为有内置函数可以做到,但你可以自己编写一个函数,如

QString treeItemToFullPath(QTreeWidgetItem* treeItem)
{
    QString fullPath= treeItem->text(0);

    while (treeItem->parent() != NULL)
    {
        fullPath= treeItem->parent()->text(0) + "/" + fullPath;
        treeItem = treeItem->parent();
    }
    return fullPath;
}

编辑:    输入treeItem是要显示其路径的选定树项。如果您确定至少选择了一个项目,则可以通过

获取
treeWidget.selectedItems().first();

另一个方法是使用工具提示。您可以为每个项目添加提示,同时将它们添加到树中,但是可以在将它们添加到最终位置后执行此操作。

更改此

for(const auto& filenamePart : filenameParts) 
{
     QTreeWidgetItem *treeItem = new QTreeWidgetItem();
     treeItem->setText(0, filenamePart);
     parentTreeItem->addChild(treeItem);
     parentTreeItem = treeItem;
}

这个

for(const auto& filenamePart : filenameParts) 
{
     QTreeWidgetItem *treeItem = new QTreeWidgetItem();
     treeItem->setText(0, filenamePart);
     parentTreeItem->addChild(treeItem);
     parentTreeItem = treeItem;
     treeItem->setToolTip(0, treeItemToFullPath(treeItem));
}

这样,只要将鼠标悬停在项目上,就会看到完整的路径。