TreeView具有类似FileSystemModel的功能

TreeView with FileSystemModel-like Functionality?

本文关键字:FileSystemModel 功能 TreeView      更新时间:2023-10-16

我正试图让QTreeView像QFileSystemModel一样发挥作用,QFileSystemModel是一个文件夹层次结构,您可以在其中浏览特定节点的子元素。唯一的问题是我希望它基于字符串数据,例如使用字符串列表"my/path/file.ext"。我尝试过使用QStringListModel,但它只是将它们放在同一级别上。

QStringListModel提供字符串列表,而不是字符串树。它不会以任何方式解释字符串。

您可以重用QStandardItemModelQStandardItem已经是一个树节点。下面这样的类可以用于将路径插入到QStandardItemModel中。

class TreeManipulator {
  Q_DISABLE_COPY(TreeManipulator)
  static QChar const m_sep;
  QMap<QString, QStandardItem*> m_items;
  QStandardItem * m_root;
  QString normalizedPath(const QString & path) {
    QStringList p(path.split(m_sep, QString::SkipEmptyParts));
    return p.join(sep);
  }
  QStandardItem * find(QStandardItem * item, const QString & child) {
    for (int i = 0; i < item->rowCount(); ++i)
      if (item->child(i)->text() == child) return item->child(i);
    return nullptr;
  }
public:
  explicit TreeManipulator(QStandardItem * root) : m_root(root) {}
  explicit  TreeManipulator(QStandardItemModel * model) : 
    m_root(model->invisibleRootItem()) {}
  QStandardItem * find(QString path) const {
    path = normalizedPath(path);
    if (m_items.contains(path)) return m_items[path];
    return nullptr;
  }
  QStandardItem * addItem(QString path) {
    QStandardItem * item = m_root;
    QStringList p(path.split(m_sep, QString::SkipEmptyParts));
    path = normalizedPath(path);
    if (m_items.contains(path)) return m_items[path];
    while (!p.isEmpty()) {
      QString elt = p.takeFirst();
      QStandardItem * child = find(item, elt);
      if (!child)
        item.appendRow((child = new QStandardItem(elt)));
      item = child;
    }
    m_items.insert(path, item);
    return item;
  }
};
QChar const TreeManipulator::m_sep(QLatin1Char('/'));