Автозаполнение с начала (одного из) нескольких столбцов

У меня есть данные с несколькими столбцами (например, "имя"/"фамилия" или "почтовый индекс"/"название места"), и теперь я хотел бы иметь (что-то вроде) qcompleter, который соответствует только началу каждого столбца .

Это означает, что при вводе «а» будут отображаться предложения типа «Андреа Миллер» или «Джон Адамс», но не «Джа. ne Doe" или "Tom Mмастера".

Любые подсказки, как это реализовать?


person rmweiss    schedule 20.11.2019    source источник
comment
Вы должны иметь возможность сделать это, установив filterMode в Qt::MatchStartsWith: doc. qt.io/qt-5/qcompleter.html#filterMode-prop   -  person Dimitry Ernot    schedule 20.11.2019
comment
Когда вы говорите несколько столбцов, вы имеете в виду, что строка состоит из нескольких слов?   -  person eyllanesc    schedule 20.11.2019


Ответы (1)


Обходной путь — отключить фильтрацию QCompleter и использовать QSortFilterProxyModel для пользовательской фильтрации:

import sys


from PySide2 import QtCore, QtWidgets


class FilterModel(QtCore.QSortFilterProxyModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._prefix = ""

    @property
    def prefix(self):
        return self._prefix

    @prefix.setter
    def prefix(self, prefix):
        self._prefix = prefix.lower()
        self.invalidateFilter()

    def filterAcceptsRow(self, sourceRow, sourceParent):
        if not self.prefix:
            return True
        text = (
            self.sourceModel()
            .index(sourceRow, self.filterKeyColumn(), sourceParent)
            .data()
        )
        for word in text.split():
            if word.lower().startswith(self.prefix):
                return True
        return False


class Completer(QtWidgets.QCompleter):
    def setModel(self, model):
        proxy_internal_model = FilterModel(self)
        proxy_internal_model.setSourceModel(model)
        model.setParent(proxy_internal_model)
        super().setModel(proxy_internal_model)

    def splitPath(self, path):
        if isinstance(self.model(), FilterModel):
            self.model().prefix = path
        return [""]


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QLineEdit()
    texts = ["Andrea Miller", "John Adams", "Jane Doe", "Tom Masters"]
    completer = Completer(w)
    completer.setModel(QtCore.QStringListModel(texts, w))
    w.setCompleter(completer)
    w.show()
    sys.exit(app.exec_())
person eyllanesc    schedule 20.11.2019