2017-10-11 257 views
1

我在下面的工作示例中添加了搜索过滤器功能。我觉得我这样做是过度的。它是从我在网上找到的项目拼凑而成的。我真的必须创建这整个SearchProxyFilter在我的项目清单上做一个简单的字符串过滤搜索吗?在QTreeview Pyside中搜索过滤器

我有一种感觉,我做错了什么或比我需要更多。任何建议,将不胜感激。

enter image description here

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

回答

1

这可以更简单地用QCompleter来完成:

class UserBrowser(QtGui.QDialog): 
    ...  
    def initUI(self): 
     ... 
     self.completer = QtGui.QCompleter(self) 
     self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) 
     self.completer.setModelSorting(
      QtGui.QCompleter.CaseInsensitivelySortedModel) 

     self.ui_items = QtGui.QTreeView() 
     self.ui_items.setModel(self.completer.completionModel()) 
     ... 
     self.create_model() 
     ...  
     self.ui_search.textChanged.connect(self.completer.setCompletionPrefix) 

    # Methods 
    def create_model(self): 
     users = ['kevin','Marry','Doug','Leslie','Michelle','John'] 
     users.sort(key=str.lower) 
     self.completer.setModel(QtGui.QStringListModel(users)) 
+0

我觉得我是在复杂的事情。谢谢:) – JokerMartini

+0

是否有可能让搜索看起来文字是'in'而不是'从' – JokerMartini

+0

@JokerMartini开始。是的 - 但如果你尝试实施它,你可能会退到你开始的地方。例如,请参阅[此问题](https://stackoverflow.com/q/5129211/984421)。不幸的是,我看不到任何简单的方法来覆盖'QCompleter'使用的默认过滤机制。有[setFilterMode](https://doc.qt.io/qt-5/qcompleter.html#filterMode-prop),它正是你想要的 - 但它只是Qt5。 – ekhumoro