text: Q:
  
  Get QTreeview index from text slug
  
  I'm trying to retrieve the model index for the QTreeView item using the given slug - which is a single string representing the treeview item's hierarchy separated by hyphens. In this case, I want to get the model index for the given slug 'Vegetable-Carrot-Blackbean':
  
  My current function always returns "Vegetable" and I feel like the way it's written I'd expect it to continually loop through a given index's children until it fails, returning the last found tree item:
  import os, sys
  from Qt import QtWidgets, QtGui, QtCore
  
  class CategoryView(QtWidgets.QWidget):
  
      def __init__(self):
          QtWidgets.QWidget.__init__(self)
          self.resize(250,400)
  
          self.categoryModel = QtGui.QStandardItemModel()
          self.categoryModel.setHorizontalHeaderLabels(['Items'])
  
          self.categoryProxyModel = QtCore.QSortFilterProxyModel()
          self.categoryProxyModel.setSourceModel(self.categoryModel)
          self.categoryProxyModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
          self.categoryProxyModel.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive)
          self.categoryProxyModel.setDynamicSortFilter(True)
  
          self.uiTreeView = QtWidgets.QTreeView()
          self.uiTreeView.setModel(self.categoryProxyModel)
          self.uiTreeView.sortByColumn(0, QtCore.Qt.AscendingOrder)
  
          self.layout = QtWidgets.QVBoxLayout()
          self.layout.addWidget(self.uiTreeView)
          self.setLayout(self.layout)
  
      def appendCategorySlug(self, slug):
          parts = slug.split('-')
          parent = self.categoryModel.invisibleRootItem()
          for name in parts:
              for row in range(parent.rowCount()):
                  child = parent.child(row)
                  if child.text() == name:
                      parent = child
                      break
              else:
                  item = QtGui.QStandardItem(name)
                  parent.appendRow(item)
                  parent = item
  
      def getIndexBySlug(self, slug):
          parts = slug.split('-')
          index = QtCore.QModelIndex()
  
          if not parts:
              return index
  
          root = self.categoryModel.index(0, 0)
          for x in parts:
              indexes = self.categoryModel.match(root, QtCore.Qt.DisplayRole, x, 1, QtCore.Qt.MatchExactly)
              if indexes:
                  index = indexes[0]
                  root = index
  
          print index, index.data()
          return index
  
  def test_CategoryView():
      app = QtWidgets.QApplication(sys.argv)
      ex = CategoryView()
      ex.appendCategorySlug('Fruit-Apple')
      ex.appendCategorySlug('Fruit-Orange')
      ex.appendCategorySlug('Vegetable-Lettuce')
      ex.appendCategorySlug('Fruit-Kiwi')
      ex.appendCategorySlug('Vegetable-Carrot')
      ex.appendCategorySlug('Vegetable-Carrot-Blackbean')
      ex.appendCategorySlug('Vegan-Meat-Blackbean')
  
      ex.getIndexBySlug('Vegetable-Carrot-Blackbean')
  
      ex.show()
      sys.exit(app.exec_())
  
  if __name__ == '__main__':
      pass
      test_CategoryView()
  
  A:
  
  The reason your current implementation doesn't work is that the start argument of match() needs to be valid index. The invisisble root item can never be valid because its row and column will always be -1. So, instead, you must use the the model's index() function to try to get the first child index of the current parent. You also need to make sure that an invalid index is returned when any part of the slug cannot be matched, otherwise you could wrongly end up returning an ancestor index.
  Here's a method that implements all that:
  def getIndexBySlug(self, slug):
      parts = slug.split('-')
      indexes = [self.categoryModel.invisibleRootItem().index()]
      for name in parts:
          indexes = self.categoryModel.match(
              self.categoryModel.index(0, 0, indexes[0]),
              QtCore.Qt.DisplayRole, name, 1,
              QtCore.Qt.MatchExactly)
          if not indexes:
              return QtCore.QModelIndex()
      return indexes[0]
  
  As an alternative, you might want to consider returning an item instead, as that will then give you access to the whole QStandardItem API (and the index can be still be easily obtained via item.index()):
  def itemFromSlug(self, slug):
      item = None
      parent = self.categoryModel.invisibleRootItem()
      for name in slug.split('-'):
          for row in range(parent.rowCount()):
              item = parent.child(row)
              if item.text() == name:
                  parent = item
                  break
          else:
              item = None
              break
      return item
  
  But note that this returns None if the slug cannot be found (although it could easily be tweaked to return the invisible root item instead).
  
  