Search code examples
pythonuser-interfacepyqt5python-3.6qcompleter

How to set a QCompleter model post construction


I just started with PyQt5 and have a small file here:

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setMinimumWidth(350)

        layout = QGridLayout()
        self.setLayout(layout)

        self.completer = QCompleter()
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.completer.setMaxVisibleItems(10)

        self.lineedit = QLineEdit()
        self.lineedit.setCompleter(self.completer)
        self.lineedit.setFixedHeight(30)
        self.lineedit.setFixedWidth(300)
        #self.lineedit.returnPressed.connect(self.show_selected)
        self.lineedit.textChanged.connect(self.text_changed)

        layout.addWidget(self.lineedit,0,0)

    def text_changed(self):
        #the function get_request returns a list of names taken from 
        #a database e.g ['matthew','mark','morris','mickey']
        vals = self.get_request(self.lineedit.text())
        self.completer.setModel(vals)

app = QApplication(sys.argv)

screen = Window()

sys.exit(app.exec_())

and my problem is this error:

TypeError: setModel(self, QAbstractItemModel): argument 1 has unexpected type 'list'

everytime i run the above code.So my question is: Exactly what am i doing wrong here,i just started with pyqt5 here and as my first program,i instantly get this error.As a side note,when I use a fixed list and put it in the QCompleterconstructor the program works,however this is not an option since i need the results to change with the user typing


Solution

  • You need to update the QStringListModel via setStringList()

    import sys
    from PyQt5.QtWidgets import QApplication, QLineEdit, QWidget, QGridLayout, QCompleter
    from PyQt5.QtCore import Qt
    
    class Window(QWidget):
        def __init__(self):
            QWidget.__init__(self)
            self.setMinimumWidth(350)
    
            layout = QGridLayout()
            self.setLayout(layout)
    
            self.completer = QCompleter([])  # Initialze with a list...to establish QStringListModel
            self.completer.setCaseSensitivity(Qt.CaseInsensitive)
            self.completer.setCompletionMode(QCompleter.PopupCompletion)
            self.completer.setMaxVisibleItems(10)
    
            self.lineedit = QLineEdit()
            self.lineedit.setCompleter(self.completer)
            self.lineedit.setFixedHeight(30)
            self.lineedit.setFixedWidth(300)
            self.lineedit.textChanged.connect(self.text_changed)
            layout.addWidget(self.lineedit,0,0)
    
        def get_request(self, line_text):
            if not line_text:
                return []
            char = line_text[0]
            if char == 'a':
                return ['aaa', 'abba', 'abby']
            if char == 'm':
                return ['matthew','mark','morris','mickey']
            return ['foo', 'bar', 'baz']
    
        def text_changed(self):
            #the function get_request returns a list of names taken from
            #a database e.g ['matthew','mark','morris','mickey']
            vals = self.get_request(self.lineedit.text())
    
            model = self.completer.model()
            model.setStringList(vals)  # Updated the QStringListModel string list
    
    app = QApplication(sys.argv)
    
    screen = Window()
    screen.show()
    
    sys.exit(app.exec_())