Как настроить правила завершения QCompleter с помощью QSortFilterProxyModel?

например, у меня есть эти три элемента в раскрывающемся списке QComboBox

chicken soup
chilli peppers
grilled chicken

ввод «ch» будет соответствовать «куриный суп» и «перец чили», но не «курица-гриль».

Я хочу иметь возможность ввести «ch» и сопоставить их все или, более конкретно, «курица» и сопоставить «куриный суп» и «курица-гриль».

ссылка: https://bugreports.qt-project.org/browse/QTBUG-7830

следующий код работает только один раз, почему? если вы введете «а», все строки, содержащие «а», отобразятся правильно, вы получите 3 результата: «Джейн Доу», «Альберт Эйнштейн», «Альфред Э. Ньюман», но если вы продолжите вводить «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_())

person Shuman    schedule 07.02.2013    source источник
comment
Этот код работает нормально для меня. Ввод an открывает всплывающее окно с 3 вариантами.   -  person Avaris    schedule 07.02.2013


Ответы (1)


добавление следующего кода в конец метода updateModel завершающего решения решает проблему, но я не знаю, почему это работает.

cr=QRect(QPoint(1, 1), QSize(1, 1))
self.complete(cr)
person Shuman    schedule 08.02.2013