代码之家  ›  专栏  ›  技术社区  ›  oğuzhan kaynar

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

  •  4
  • oğuzhan kaynar  · 技术社区  · 9 年前

    我有一个简单的 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

    2 回复  |  直到 9 年前
        1
  •  3
  •   t.m. Andrey Chaschev    9 年前

    嗯,我不认为有一个内置函数可以做到这一点,但是你可以自己编写一个函数

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

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

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

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

        2
  •  2
  •   Kuba hasn't forgotten Monica    9 年前

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

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

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

    如果树很大,存储规范化的模型将使用更少的内存。考虑到项目的选择可能很少,因为它是在显式用户输入的情况下进行的,因此迭代树以提取完整路径的成本很小。人类在捣乱按键或鼠标按钮时并不是那么快。

    该示例演示了两种方法:

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