2017-10-11 256 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