title: Search Filter in QTreeview Pyside
body: <p>I have a working sample below that adds the search filter functionality. I feel like how I'm doing it is overkill. It was pieced together from projects I've found online. Do i really have to create this entire SearchProxyFilter to do a simple string filtering search on my list of items?</p>
  
  <p>I have a feeling that I'm doing something wrong or more than i need to. Any suggestions would be appreciated.</p>
  
  <p><a href="https://i.stack.imgur.com/RQvAs.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RQvAs.png" alt="enter image description here"></a></p>
  
  <pre><code>#######
  # Imports
  #######
  import sys
  import os
  from PySide import QtGui, QtCore
  
  #######
  # Main
  #######
  class SortModel(QtGui.QSortFilterProxyModel):
  
      def __init__(self, *args, **kwargs):
          super(SortModel, self).__init__(*args, **kwargs)
          self._pattern = ''
  
      @property
      def pattern(self):
          return self._pattern
  
      def filterAcceptsRow(self, sourceRow, sourceParent):
          if not self.pattern:
              return True
  
          sm = self.sourceModel()
          modelIdx = sm.index(sourceRow, 0)
          if modelIdx.isValid():
              txt = modelIdx.data(role=QtCore.Qt.DisplayRole)
              if not self.pattern.lower() in txt.lower():
                  return False
  
          return True
  
      def lessThan(self, left, right):
          leftData = self.sourceModel().data(left)
          rightData = self.sourceModel().data(right)
  
          if leftData:
              leftData = leftData.lower()
          if rightData:
              rightData = rightData.lower()
  
          return leftData &lt; rightData
  
  class UserBrowser(QtGui.QDialog):
  
      def __init__(self, parent=None):
          super(UserBrowser, self).__init__(parent)
          self.resize(300, 500)
          self.setWindowTitle('Users')
          self.setModal(True)
          self.initUI()
  
      def initUI(self):
          self.results = ''
          self.filepath = ''
  
          self.ui_search = QtGui.QLineEdit()
          self.ui_search.setPlaceholderText('Search...')
  
          self.source_model = QtGui.QStandardItemModel()
          self.user_model = SortModel(self)
          self.user_model.setSourceModel(self.source_model)
          self.user_model.setDynamicSortFilter(True)
          self.user_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
  
          self.ui_items = QtGui.QTreeView()
          self.ui_items.setModel(self.user_model)
          self.ui_items.setAlternatingRowColors(False)
          self.ui_items.setSortingEnabled(True)
          self.ui_items.sortByColumn(0, QtCore.Qt.AscendingOrder)
          self.ui_items.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
          self.ui_items.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
          self.ui_items.setHeaderHidden(True)
          self.ui_items.setRootIsDecorated(False)
  
          gdl = QtGui.QGridLayout()
          gdl.setContentsMargins(10, 10, 10, 10)
          gdl.addWidget(self.ui_search, 0, 0)
          gdl.addWidget(self.ui_items, 1, 0)
          self.setLayout(gdl)
          self.create_model()
  
          self.ui_search.textChanged.connect(self.changed_text)
  
      # Methods
      def create_model(self):
          model = self.source_model
          model.clear()
          model.setHorizontalHeaderLabels(['Names'])
  
          users = ['kevin','Marry','Doug','Leslie','Michelle','John']
          for x in users:
              item = QtGui.QStandardItem()
              item.setData(x , role=QtCore.Qt.DisplayRole)
              model.appendRow(item)
  
          self.ui_items.sortByColumn(0, QtCore.Qt.AscendingOrder)
  
      # Actions
      def changed_text(self, text):
          self.user_model._pattern = text
          self.user_model.invalidateFilter()
  
  def main():
      app = QtGui.QApplication(sys.argv)
      ex = UserBrowser()
      ex.show()
      sys.exit(app.exec_())
  
  if __name__ == '__main__':
      main()
  </code></pre>