QComboBox с автодополнением работает в PyQt4, но не в PySide

У меня есть поле со списком с настраиваемым завершением, которое отлично работает в PyQt4, но не работает в PySide.

Я убедился, что новый завершающий модуль заменяет встроенный завершающий модуль QComboBox, поскольку встроенное завершение больше не выполняется. Однако при запуске с PySide завершитель не появляется во всплывающем окне с отфильтрованным списком параметров.

Я также пытался обеспечить, чтобы весь текст был полностью str или весь unicode, чтобы избежать различий между PyQt API 1 с QStrings и использованием PySide типов юникода Python. Изменение типов текста не повлияло ни на PyQt, ни на поведение PySide (PyQt продолжает работать, PySide не работает).

Вот мой код:

from PySide import QtCore
from PySide import QtGui 

#from PyQt4 import QtCore
#from PyQt4 import QtGui


class AdvComboBox(QtGui.QComboBox):
    def __init__(self, parent=None):
        super(AdvComboBox, self).__init__(parent)

        self.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QtGui.QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QtGui.QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QtGui.QCompleter.UnfilteredPopupCompletion)

        self.setCompleter(self.completer)

        # connect signals

        def filter(text):
            print "Edited: ", text, "type: ", type(text)
            self.pFilterModel.setFilterFixedString(str(text))

        self.lineEdit().textEdited[unicode].connect(filter)
        self.completer.activated.connect(self.on_completer_activated)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        print "activated"
        if text:
            print "text: ", text
            index = self.findText(str(text))
            print "index: ", index
            self.setCurrentIndex(index)


    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(AdvComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)


    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(AdvComboBox, self).setModelColumn(column)


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)

    combo = AdvComboBox()

    names = ['bob', 'fred', 'bobby', 'frederick', 'charles', 'charlie', 'rob']

    # fill the standard model of the combobox
    combo.addItems(names)
    combo.setModelColumn(0)
    combo.resize(300, 40)
    combo.show()

    sys.exit(app.exec_())

person flutefreak7    schedule 27.06.2014    source источник


Ответы (1)


Я понял это, когда писал вопрос...

Похоже, что хотя документация PySide QCompleter перечисляет вариант инициализации QCompleter с моделью и родителем, на самом деле он не работает.

Решение состоит в том, чтобы установить модель компоновщика после его инициализации.

Вот рабочий код:

from PySide import QtCore
from PySide import QtGui 


class AdvComboBox(QtGui.QComboBox):
    def __init__(self, parent=None):
        super(AdvComboBox, self).__init__(parent)

        self.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QtGui.QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer
        self.completer = QtGui.QCompleter(self)
        #Set the model that the QCompleter uses
        # - in PySide doing this as a separate step worked better
        self.completer.setModel(self.pFilterModel)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QtGui.QCompleter.UnfilteredPopupCompletion)

        self.setCompleter(self.completer)

        # connect signals

        def filter(text):
            print "Edited: ", text, "type: ", type(text)
            self.pFilterModel.setFilterFixedString(str(text))

        self.lineEdit().textEdited[unicode].connect(filter)
        self.completer.activated.connect(self.on_completer_activated)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        print "activated"
        if text:
            print "text: ", text
            index = self.findText(str(text))
            print "index: ", index
            self.setCurrentIndex(index)


    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(AdvComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)


    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(AdvComboBox, self).setModelColumn(column)


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)

    combo = AdvComboBox()

    names = ['bob', 'fred', 'bobby', 'frederick', 'charles', 'charlie', 'rob']

    # fill the standard model of the combobox
    combo.addItems(names)
    combo.setModelColumn(0)
    combo.resize(300, 40)
    combo.show()

    sys.exit(app.exec_())
person flutefreak7    schedule 27.06.2014
comment
Возможно, вы захотите отправить отчет об ошибке :) - person three_pineapples; 28.06.2014
comment
Посмотрел его, и, похоже, он уже был подан: bugreports.qt-project.org/ просмотреть/PYSIDE-203 - person flutefreak7; 28.06.2014