Thursday, 24 June 2021

Highlighting the first filtered value from combo box

I am trying to create a combo box widget which filters the values based on user input and highlight them. With some surfing I was able to almost complete it. The widget is able to filter the values from the drop down. But it is not highlighting the first available value in the dropdown, when there is not exact match as we type in the editable lineedit. Following is the code

import sys, os
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

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

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

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

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

        # connect signals
        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
        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):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))



    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedComboBox, 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(ExtendedComboBox, self).setModelColumn(column)
        
class Application(QWidget):
    def __init__(self):
        super().__init__()
        items = set(
            "You can use QCompleter to provide auto completions in any Qt widget, such as QLineEdit and QComboBox. When the user starts typing a word, QCompleter suggests possible ways of completing the word, based on a word list.".split(
                ' '))
        layout = QVBoxLayout(self)
        cb = ExtendedComboBox(self)
        cb.addItems(items)
        cb.setCurrentText("")
        layout.addWidget(cb)
        layout.addStretch(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    diag = Application()
    diag.show()
    sys.exit(app.exec_())

When running this code we get the following window and when I type "an" you can see "and" is highlighted for ref

When we type any letter not matching from beginning it is not highlighting. Please refer the below image

next image

I want the 'provide' to be highlighted in above case. Any suggestions could be helpful.

And moreover for case sensitivity also the same issue if the case is not matching, it is not highlighting the match.



from Highlighting the first filtered value from combo box

No comments:

Post a Comment