如何使用QSortFilterProxyModel自定义QCompleter完成规则?

问题描述:

例如,我在我的QComboBox下拉列表如何使用QSortFilterProxyModel自定义QCompleter完成规则?

chicken soup 
chilli peppers 
grilled chicken 

进入“CH”将匹配“鸡汤”和“辣椒”,而不是“烤鸡”这三个项目。

我想要的是能够输入“ch”并匹配所有这些或更具体地说,“鸡”,并匹配“鸡汤”和“烤鸡肉”。

参考: https://bugreports.qt-project.org/browse/QTBUG-7830

下面的代码工作只有一次,为什么呢? 如果输入'a',所有包含'a'的字符串都显示正确,则返回3个结果,'Jane Doe','Albert Einstein','Alfred E Newman' 但如果继续输入'n'没有结果显示在下拉菜单中。

编辑:它的工作原理,但无法正确显示弹出而QListView(如果按向下箭头键,符合条件的商品将在下拉列表编辑区显示,但下拉列表中未显示)

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

from PyQt4 import QtGui,QtCore 

import sys 

import signal 
signal.signal(signal.SIGINT, signal.SIG_DFL) 


class MyGui(QDialog): 

    def __init__(self, parent=None): 

     super(MyGui,self).__init__(parent) 

     model = QtGui.QStringListModel() 
     wordList = ['John Doe','Jane Doe','Albert Einstein', 'Alfred E Newman'] 
     model.setStringList(wordList) 

     layout = QtGui.QVBoxLayout(self) 
     self.line = QtGui.QLineEdit(self) 
     layout.addWidget(self.line) 

     self.combobox = QComboBox(parent) 
     layout.addWidget(self.combobox) 
     self.combobox.addItems(wordList) 
     self.combobox.setEditable(True) 

     self.setLayout(layout) 

     complete = CustomQCompleter2(self) 
     complete.setModel(model) 
     complete.setCaseSensitivity(QtCore.Qt.CaseInsensitive) 
     complete.setCompletionMode(QCompleter.UnfilteredPopupCompletion) 
     complete.setWrapAround(False) 

     self.line.setCompleter(complete) 
     self.combobox.setCompleter(complete) 
     self.combobox.setEditText('') 

     self.setGeometry(200, 100, 400, 300) 


class CustomQCompleter2(QCompleter): 
    def __init__(self, parent=None): 
     super(CustomQCompleter2, self).__init__(parent) 
     self.local_completion_prefix = "" 
     self.source_model = None 

    def setModel(self, model): 
     self.source_model = model 
     super(CustomQCompleter2, self).setModel(self.source_model) 

    def updateModel(self): 
     local_completion_prefix = self.local_completion_prefix 
     class InnerProxyModel(QSortFilterProxyModel): 
      def filterAcceptsRow(self, sourceRow, sourceParent): 
       index0 = self.sourceModel().index(sourceRow, 0, sourceParent) 
       searchStr = local_completion_prefix.lower() 
       modelStr = self.sourceModel().data(index0,Qt.DisplayRole).toString().toLower() 
       print searchStr,' in ',modelStr, searchStr in modelStr 
       return searchStr in modelStr 


     proxy_model = InnerProxyModel() 

     proxy_model.setSourceModel(self.source_model) 

     super(CustomQCompleter2, self).setModel(proxy_model) 
     print 'match :',proxy_model.rowCount() 


    def splitPath(self, path): 
     self.local_completion_prefix = str(path) 
     self.updateModel() 
     return "" 

if __name__ == '__main__': 

    app = QtGui.QApplication(sys.argv) 
    gui = MyGui() 
    gui.show() 
    sys.exit(app.exec_()) 
+0

这段代码对我来说工作正常。输入'an'可以打开3个选项。 – Avaris

将下面的代码添加到updateModel的结尾解决问题的方法,但我不知道它为什么起作用。

cr=QRect(QPoint(1, 1), QSize(1, 1)) 
self.complete(cr)