Qt QCompleter 多重匹配

发布于 2024-09-24 08:01:53 字数 202 浏览 8 评论 0原文

我试图使 QCompleter 匹配几个用逗号分隔的等效选项。似乎没有简单的方法可以做到这一点,但是 QCompleter 引用的一行引起了我的注意,它描述了函数 QCompleter::splitPath:“当与列表模型一起使用时,返回列表中的第一项用于匹配。”这可以按照我需要的方式使用 - 分割输入字符串并返回它,以便未完成的最后一项是列表中的第一项?我没能成功,但我可能做错了什么。

I am trying to make QCompleter match several equivalent options which are separated with commas. There seemingly is no easy way to do that, but one line of QCompleter reference caught my attention, describing function QCompleter::splitPath: "When used with list models, the first item in the returned list is used for matching." Could this be used in the way I need - split the input string and return it so the unfinished last item is the first in the list? I didn't manage to make it work, but I may be doing something wrong.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如梦亦如幻 2024-10-01 08:01:53

这是我认为更符合原始问题的另一种方法。不需要复杂的数据模型,使用简单的 QStringListModel 代替。

import sys
from PyQt4 import QtCore, QtGui

class test(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        model = QtGui.QStringListModel()
        wordList = ['John Doe','Jane Doe','Albert Einstein', 'Alfred E Newman']
        model.setStringList(wordList)

        layout = QtGui.QVBoxLayout(self)
        self.line = QtGui.QLineEdit(self)
        layout.addWidget(self.line)

        complete = CustomCompleter(self)
        complete.setModel(model)
        complete.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
        complete.setCompletionMode(0)
        complete.setWrapAround(False)

        self.line.setCompleter(complete)


class CustomCompleter(QtGui.QCompleter):
    def __init__(self, parent=None):
        QtGui.QCompleter.__init__(self, parent)

    def pathFromIndex(self, index):
        path = QtGui.QCompleter.pathFromIndex(self, index)

        lst = str(self.widget().text()).split(',')
        if len(lst) > 1:
            path = '%s, %s' % (','.join(lst[:-1]), path)

        return path

    def splitPath(self, path):
        path = str(path.split(',')[-1]).lstrip(' ')
        return [path]

#===============================================================================
# Unit Testing
#===============================================================================
if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = test()
    window.show()
    sys.exit(app.exec_())

Here is another way of doing it that I think is more in line with the original question. No need for a complex data model, uses a simple QStringListModel instead.

import sys
from PyQt4 import QtCore, QtGui

class test(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        model = QtGui.QStringListModel()
        wordList = ['John Doe','Jane Doe','Albert Einstein', 'Alfred E Newman']
        model.setStringList(wordList)

        layout = QtGui.QVBoxLayout(self)
        self.line = QtGui.QLineEdit(self)
        layout.addWidget(self.line)

        complete = CustomCompleter(self)
        complete.setModel(model)
        complete.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
        complete.setCompletionMode(0)
        complete.setWrapAround(False)

        self.line.setCompleter(complete)


class CustomCompleter(QtGui.QCompleter):
    def __init__(self, parent=None):
        QtGui.QCompleter.__init__(self, parent)

    def pathFromIndex(self, index):
        path = QtGui.QCompleter.pathFromIndex(self, index)

        lst = str(self.widget().text()).split(',')
        if len(lst) > 1:
            path = '%s, %s' % (','.join(lst[:-1]), path)

        return path

    def splitPath(self, path):
        path = str(path.split(',')[-1]).lstrip(' ')
        return [path]

#===============================================================================
# Unit Testing
#===============================================================================
if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = test()
    window.show()
    sys.exit(app.exec_())
云巢 2024-10-01 08:01:53

根据我从您的问题和文档中了解到的情况,您可以用逗号分隔用户输入的字符串,并让您的完成者检查您的模型以完成。

但是,在每个逗号之后,模型的索引(将其想象为二维字符串数组)将递增。

例如,如果您有以下输入:

ABCD、EFGH、IJ

,并且您希望完成者完成 IJ KL,则您的模型必须至少有 3 个索引宽,因为第一个文本 (ABCD) 将使用第一列中的字符串完成,EFGH 将使用模型的第二列完成,等等。

所以,我不知道它是否可以在您的应用程序中使用。

祝你好运。

From what I understand from your question and the doc, you could separate the user-inputted string with commas and make your completer check in your model for a completion.

BUT, after each comma, the index of your model (figure it like a two-dimension array of string) will be incremented.

For example, if you have the following input:

ABCD, EFGH, IJ

and you would like to the completer to finish IJ KL, you would have to have a model that is at least 3 indexes wide because the first text (ABCD) would be completed with the strings in the first column, EFGH would be completed with the second column of your model, etc.

So, I don't know if it could be used in your application.

Best of luck.

红焚 2024-10-01 08:01:53

支持成员 DELIMITERS 中所有分隔符的通用多重完成器代码可以在下面的代码片段中找到。这看起来很简单,但由于 pyQt 方面的文档非常糟糕,调试起来非常烦人。

class CustomCompleter(QtGui.QCompleter):
    DELIMITERS = r'[()\[\]*+-=/\\]'
    def __init__(self, parent=None):
        QtGui.QCompleter.__init__(self, parent)
    def pathFromIndex(self, index):
        path = QtGui.QCompleter.pathFromIndex(self, index)
        string = self.widget().text()
        split = re.split(self.DELIMITERS, string)[-1]
        if len(split)==len(string):
            string_without_split = ''
        else:
            if len(split)>0:
                string_without_split = string[:-len(split)]
            else:
                string_without_split = string
        return string_without_split+path

    def splitPath(self, path):
        split = re.split(self.DELIMITERS, path)[-1]
        return [split]

General purpose multi-completer code which supports all separators in the member DELIMITERS can be found in the code snip below. It seems easy but it was very annoying to debug due to very bad documentation on the pyQt side.

class CustomCompleter(QtGui.QCompleter):
    DELIMITERS = r'[()\[\]*+-=/\\]'
    def __init__(self, parent=None):
        QtGui.QCompleter.__init__(self, parent)
    def pathFromIndex(self, index):
        path = QtGui.QCompleter.pathFromIndex(self, index)
        string = self.widget().text()
        split = re.split(self.DELIMITERS, string)[-1]
        if len(split)==len(string):
            string_without_split = ''
        else:
            if len(split)>0:
                string_without_split = string[:-len(split)]
            else:
                string_without_split = string
        return string_without_split+path

    def splitPath(self, path):
        split = re.split(self.DELIMITERS, path)[-1]
        return [split]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文