qtqt4qt4.6qcomboboxqcompleter

QCompleter Custom Completion Rules


I'm using Qt4.6 and I have a QComboBox with a QCompleter in it.

The usual functionality is to provide completion hints (these can be in a dropdown rather than inline - which is my usage) based on a prefix. For example, given

chicken soup
chilli peppers
grilled chicken

entering ch would match chicken soup and chilli peppers but not grilled chicken.

What I want is to be able to enter ch and match all of them or, more specifically, chicken and match chicken soup and grilled chicken.
I also want to be able to assign a tag like chs to chicken soup to produce another match which is not just on the text's content. I can handle the algorithm but,

Which of QCompleter's functions do I need to override?
I'm not really sure where I should be looking...


Solution

  • Based on @j3frea suggestion, here is a working example (using PySide). It appears that the model needs to be set every time splitPath is called (setting the proxy once in setModel doesn't work).

    combobox.setEditable(True)
    combobox.setInsertPolicy(QComboBox.NoInsert)
    
    class CustomQCompleter(QCompleter):
        def __init__(self, parent=None):
            super(CustomQCompleter, self).__init__(parent)
            self.local_completion_prefix = ""
            self.source_model = None
    
        def setModel(self, model):
            self.source_model = model
            super(CustomQCompleter, 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)
                    return local_completion_prefix.lower() in self.sourceModel().data(index0).lower()
            proxy_model = InnerProxyModel()
            proxy_model.setSourceModel(self.source_model)
            super(CustomQCompleter, self).setModel(proxy_model)
    
        def splitPath(self, path):
            self.local_completion_prefix = path
            self.updateModel()
            return ""
    
    
    completer = CustomQCompleter(combobox)
    completer.setCompletionMode(QCompleter.PopupCompletion)
    completer.setModel(combobox.model())
    
    combobox.setCompleter(completer)