PyQt5 - Не получается получить нужный элемент, выбрав опцию QComboBox с помощью мыши - PullRequest
0 голосов
/ 31 марта 2020

Мне нужно иметь QComboBox с возможностью фильтрации элементов на основе ввода текста. Пока все работает нормально, когда я что-то пишу в текстовом вводе, однако, если я ничего не набираю и использую только мышь, я не получаю ожидаемого поведения.

Контрольные примеры:

  • Выполните поиск в выпадающем списке, написав что-либо в поле «Ввод текста», а затем щелкните мышью или нажмите «Ввод» (все работает как положено);
  • Если щелкните в выпадающем списке, а затем выберите опция без типа что-либо вызывает "on_mouse_pressed", но в результате это не ожидаемый результат.

Почему я не получаю правильную опцию, когда нажимаю на нее? (в "on_mouse_pressed")

Я пытался использовать сигнал currentTextChanged вместо «нажатой», но в моем случае он запускается несколько раз из-за сигнала «активировать» завершителя.

Мой код сейчас:

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QSortFilterProxyModel
from PyQt5.QtWidgets import QCompleter, QComboBox

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

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

        # 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.view().pressed.connect(self.on_mouse_pressed)
        self.completer.activated.connect(self.on_completer_activated)

    def on_mouse_pressed(self, index):
        print("handle: ", index)#self.itemText(self.currentIndex()))
        print(self.currentIndex())
        print(self.currentText())

    # on selection of an item from the completer, select the corresponding item from combobox 
    # def on_completer_activated(self, index):
    def on_completer_activated(self, text):
        print("on_completer_activated: ",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)    


if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtCore import QStringListModel

    app = QApplication(sys.argv)

    string_list = [None, 'abc', 'abse', 'alphabetic', 'audiophonic', 'blue', 'blind', 'c1ar', 'c1are', 'car', 'cmsns', 'custom_opt', 'dare', 'ddxpto2', 'ddxpto3', 'ddxpto31']

    combo = ExtendedComboBox()

    # either fill the standard model of the combobox
    combo.addItems(string_list)

    # or use another model
    #combo.setModel(QStringListModel(string_list))

    combo.resize(300, 40)
    combo.show()

    sys.exit(app.exec_())```


...