【问题标题】:Customize QCompleter with QSortFilterProxyModel使用 QSortFilterProxyModel 自定义 QCompleter
【发布时间】:2019-07-08 03:35:16
【问题描述】:

我想为QLineEditQCompleter 启用通配符匹配。如果字符串模型是['abc', 'cba'],当我输入ab*a* 时,它应该显示abc。下面是我写的代码,但它仍然表现得像一个常规匹配。知道我应该如何解决它吗?

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys, random


class MyCompleter(QCompleter):
    def __init__(self, *args):
        super().__init__(*args)

    def setModel(self, model):
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setSourceModel(model)
        super().setModel(self.proxyModel)

    def updatePattern(self, patternStr):
        self.proxyModel.setFilterWildcard(patternStr)


class MyMain(QMainWindow):
    def __init__(self, *args):
        super().__init__(*args)
        self.initUI()

    def initUI(self):
        model = QStringListModel(['abc', 'cba'])

        completer = MyCompleter()
        completer.setModel(model)

        searchBar = QLineEdit(self)
        searchBar.setCompleter(completer)
        searchBar.textChanged.connect(lambda wildcard: completer.updatePattern(wildcard))

        vLayout = QVBoxLayout()
        vLayout.addWidget(searchBar, alignment=Qt.AlignCenter)

        self.setCentralWidget(QWidget())
        self.centralWidget().setLayout(vLayout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mm = MyMain()
    mm.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5


    【解决方案1】:

    试试看:

    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class LineEdit(QLineEdit):                                     # +++
        def __init__(self, *args, **kwargs):
            QLineEdit.__init__(self, *args, **kwargs)
            self.multipleCompleter = None
    
        def keyPressEvent(self, event):
            QLineEdit.keyPressEvent(self, event)
            if not self.multipleCompleter:
                return
            c = self.multipleCompleter
    
            if self.text() == "":                                    
                return
            c.setCompletionPrefix(self.cursorWord(self.text()))      
    
            if len(c.completionPrefix()) < 1:
                c.popup().hide()
                return
            c.complete()
    
        def cursorWord(self, sentence):
            p = sentence.rfind(" ")
            if p == -1:
                return sentence
            return sentence[p + 1:]
    
        def insertCompletion(self, text):                             
            p = self.text().rfind(" ")                                
            if p == -1:
                self.setText(text)                                    
            else:
                self.setText(self.text()[:p+1]+ text)           
    
        def setMultipleCompleter(self, completer):
            self.multipleCompleter = completer
            self.multipleCompleter.setWidget(self)
            completer.activated.connect(self.insertCompletion)
    
    
    class MyCompleter(QCompleter):
        def __init__(self, *args):
            super().__init__(*args)
    
        def setModel(self, model):
            self.proxyModel = QSortFilterProxyModel()
            self.proxyModel.setSourceModel(model)
            super().setModel(self.proxyModel)
    
        def updatePattern(self, patternStr):
            print(f"patternStr-> {patternStr}")
            self.proxyModel.setFilterWildcard(patternStr)
    
    
    class MyMain(QMainWindow):
        def __init__(self, *args):
            super().__init__(*args)
            self.initUI()
    
        def initUI(self):
            model = QStringListModel(['abc', 'cba'])
    
            completer = MyCompleter()
            completer.setModel(model)
    
    #        searchBar = QLineEdit(self)
    #        searchBar.setCompleter(completer)
    #        searchBar.textChanged.connect(lambda wildcard: completer.updatePattern(wildcard))
    
            searchBar = LineEdit(self)                              # +++
            completer.setCaseSensitivity(Qt.CaseInsensitive)        # +++
            searchBar.setMultipleCompleter(completer)               # +++
    
            vLayout = QVBoxLayout()
            vLayout.addWidget(searchBar, alignment=Qt.AlignCenter)
            self.setCentralWidget(QWidget())
            self.centralWidget().setLayout(vLayout)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        mm = MyMain()
        mm.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 谢谢!但这不是我想要实现的。当我输入ab* 时,它应该匹配单词abc 并显示它。
    • @Einiemand 对不起,我不太明白你的意思。如果您输入 aababc 应该是什么?为什么要招募*
    • 抱歉没有澄清。 * 是通配符匹配的一部分。就像使用 git 时一样,您可以使用 git add *.py 添加所有名称以 .py 结尾的文件。在我的代码中,只要QRegExp(pattern, Qt.CaseInsensitive, QRegExp.Wildcard).match(&lt;word&gt;) 返回True,我就想显示一个单词。由于aab 都不匹配abc,因此不会显示该词。
    • @Einiemand 您写的内容应该反映在问题中。而且我没有在您使用QRegExp 的示例中看到?
    • 确实如此。我的观点是输入是模式,GUI 应该显示所有匹配模式的单词。
    猜你喜欢
    • 2013-01-22
    • 2023-04-09
    • 2017-07-04
    • 2011-07-04
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多