lineedit内容补全

 
from PyQt5.QtCore import Qt,  QStringListModel
from PyQt5.QtGui import  QTextCursor
from PyQt5.QtWidgets import QTextEdit, QCompleter
 
 
class TextEdit(QTextEdit):
    def __init__(self, searchWords_dict=dict, matchWords_list=list, parent=None):
        super(TextEdit, self).__init__(parent)
 
        self.textChangedSign = True
        self.textChanged.connect(self.dealTextChanged)
        self._completer = None
        self.searchWords_dict = searchWords_dict
        self.matchWords_list = matchWords_list
        # print(list(searchWords_dict.keys()))
        # 将传入的搜索词语匹配词整合 , 成为自动匹配选词列表
        self.initAutoCompleteWords()
        # 用户已经完成的前缀
        self.completion_prefix = ''
 
    def initAutoCompleteWords(self):
        '''
        处理autoCompleteWords_list,以及specialCursorDict
        '''
        self.autoCompleteWords_list = []
        self.specialCursorDict = {}  # 记录待选值的特殊光标位置
        for i in self.searchWords_dict:
            if "$CURSON$" in self.searchWords_dict[i]:
                cursorPosition = len(self.searchWords_dict[i]) - len("$CURSON$") - self.searchWords_dict[i].find(
                    "$CURSON$")
                self.searchWords_dict[i] = self.searchWords_dict[i].replace("$CURSON$", '')
                self.specialCursorDict[i] = cursorPosition
        for i in self.matchWords_list:
            if "$CURSON$" in i:
                cursorPosition = len(i) - len("$CURSON$") - i.find("$CURSON$")
                self.matchWords_list[self.matchWords_list.index(i)] = i.replace("$CURSON$", '')
                self.specialCursorDict[i.replace("$CURSON$", '')] = cursorPosition
 
        self.autoCompleteWords_list = list(self.searchWords_dict.keys()) + self.matchWords_list
 
    def setCompleter(self, c):
        self._completer = c
        c.setWidget(self)  # 设置Qcomplete 要关联的窗口小部件。在QLineEdit上设置QCompleter时,会自动调用此函数。在为自定义小部件提供Qcomplete时,需要手动调用。
        # 更改样式
        c.popup().setStyleSheet('''
        QListView {
            #color: #9C9C9C;
            #background-color: #4F4F4F;
        }
        QListView::item:selected //选中项
        {
            background-color: #9C9C9C;
            border: 20px solid #9C9C9C;
        }
        QListView::item:selected:active //选中并处于激活状态时
        {
            background-color: #9C9C9C;
            border: 20px solid #9C9C9C;
        }
        QListView::item {
            color: red;
            padding-top: 5px;
            padding-bottom: 5px;
        }
        QListView::item:hover {
            background-color: #9C9C9C;
        }
        QScrollBar::handle:vertical{ //滑块属性设置
            background:#4F4F4F;
            width:2px;
            height:9px;
            border: 0px;
            border-radius:100px;
            }
        QScrollBar::handle:vertical:normal{
            background-color:#4F4F4F;
            width:2px;
            height:9px;
            border: 0px;
            border-radius:100px;
            }
        QScrollBar::handle:vertical:hover{
            background:#E6E6E6;
            width:2px;
            height:9px;
            border: 0px solid #E5E5E5;
            border-radius:100px;
            }
        QScrollBar::handle:vertical:pressed{
            background:#CCCCCC;
            width:2px;
            height:9px;
            border: 0px solid #E5E5E5;
            border-radius:100px;
            }
        ''')
 
        '''下面是completer的一些属性设置,可以自行修改'''
        # setModelSorting此方法指定模型中项目的排序方式。值为枚举值
        # 分别为QCompleter.UnsortedModel QCompleter.CaseSensitivelySortedModel QCompleter.CaseInsensitivelySortedModel
        # 内容                                      值     描述
        # QCompleter.UnsortedModel                 0  该模型是未排序的。
        # QCompleter.CaseSensitivelySortedModel    1  该模型是大小写敏感的。
        # QCompleter.CaseInsensitivelySortedModel  2  模型不区分大小写。
        self._completer.setModelSorting(QCompleter.CaseSensitivelySortedModel)
        # self.completer.setCaseSensitivity 和 上述 self.completer.setModelSorting 一样 ,同时设置且不对应时setCaseSensitivity不生效
        # Qt.CaseSensitivity 该属性保持匹配的大小写敏感性。
        # self.completer.setCaseSensitivity(Qt.CaseInsensitive)
 
        # 如果filterMode设置为Qt.MatchStartsWith,则只会显示以类型化字符开头的条目。 Qt.MatchContains将显示包含类型字符的条目,并且Qt.MatchEnds以类型字符结尾的条目显示。
        # 目前,只有这三种模式得以实施。 将filterMode设置为任何其他Qt :: MatchFlag将发出警告,并且不会执行任何操作。
        # 默认模式是Qt :: MatchStartsWith。
        # 这个属性是在Qt 5.2中引入的。
        self._completer.setFilterMode(Qt.MatchContains)
 
        # 此属性在导航项目时包含完成项。默认True 这个属性是在Qt 4.3中引入的。
        self._completer.setWrapAround(False)
 
        # 设置补全模式  有三种枚举值: QCompleter.PopupCompletion(默认)  QCompleter.InlineCompletion   QCompleter.UnfilteredPopupCompletion
        # QCompleter.PopupCompletion(默认) 当前完成显示在一个弹出窗口中。
        # QCompleter.InlineCompletion  完成内联显示(作为选定的文本)。
        # QCompleter.UnfilteredPopupCompletion 所有可能的完成都显示在弹出窗口中,最有可能的建议显示为当前。
        c.setCompletionMode(QCompleter.PopupCompletion)
 
        # QCompleter.setModel(QAbstractItemModel *model)
        # 设置为模型提供QCompleter的模型。 该模型可以是列表模型或树模型。 如果一个模型已经被预先设置好了,并且它有QCompleter作为它的父项,它将被删除。
        # self.completer.setModel(completer_model)
        self._completer.setModel(QStringListModel(self.autoCompleteWords_list, self._completer))
 
        '''
        当用户激活popup()中的项目时发送此信号。 (通过点击或按回车)
        QCompleter.activated;如果文本框的当前项目发生更改,则会发出两个信号currentIndexChanged()
        和activated()。无论以编程方式或通过用户交互完成更改,currentIndexChanged()
        总是被发射,而只有当更改是由用户交互引起时才activated()
        注意: 这里的文本框项目发生改变是指QCompleter的项目添加到文本框造成的改变
        '''
        c.activated.connect(self.insertCompletion)  # 为 用户更改项目文档事件 绑定 函数
 
    def insertCompletion(self, completion):
        '''
        当用户激活popup()中的项目时调用。(通过点击或按回车)
        @competion::添加 QCompleter
        '''
 
        if self._completer.widget() is not self:  # 如果没有绑定completer跳过此事件
            return
        '''
        俩种补全方式
        1. 搜索添加 在searchWords_dict键中的对应项,删除用户输入的匹配项,自动补全其键值
        2. 匹配添加 在
        '''
        tc = self.textCursor()
        # 判断是搜索添加 还是 直接匹配添加
        if completion in self.searchWords_dict:  # 搜索添加
            # 删除输入的搜索词
            for i in self._completer.completionPrefix():
                tc.deletePreviousChar()
            # 让光标移到删除后的位置
            self.setTextCursor(tc)
 
            # 插入对应的键值
            insertText = self.searchWords_dict[completion]
            tc.insertText(insertText)
            # 关闭自动补全选项面板
            self._completer.popup().hide()
 
        else:  # 直接匹配添加
            # 计算用户输入和匹配项差值,并自动补全
            # extra = len(completion) - len(self._completer.completionPrefix())
            # self._completer.completionPrefix() 为 当前匹配项中,用户已输入的值 , 如输入 ab 匹配到 ABORT 则返回 ab
 
            # 判断用户输入单词 与 需要补全内容是否一致,一致就不用操作
            # if not self.completion_prefix == completion[-extra:]:
            # 自动补全
            # tc.insertText(completion[-extra:])
            # 关闭自动补全选项面板
            # self._completer.popup().hide()
            # 删除输入并填充关键字(解决大小写差异),先删除输入字符串,然后插入提示词
            for i in self._completer.completionPrefix():
                tc.deletePreviousChar()
            tc.insertText(completion)
            # 关闭自动补全选项面板
            self._completer.popup().hide()
        '''更改光标位置'''
        # 移动光标 ,光标位置枚举值
        # cursor_pos = QTextCursor.NoMove #光标不移动
        # cursor_pos = QTextCursor.Start #文档开头
        # cursor_pos = QTextCursor.End #文档结尾
        # cursor_pos = QTextCursor.Up #上一行
        # cursor_pos = QTextCursor.Down #下一行
        # cursor_pos = QTextCursor.Left #向左移动一字符
        # cursor_pos = QTextCursor.Right #向右移动一字符
        # cursor_pos = QTextCursor.StartOfLine  # 行首
        # cursor_pos = QTextCursor.StartOfBlock #段首
        # cursor_pos = QTextCursor.StartOfWord #单词首
        # cursor_pos = QTextCursor.EndOfLine #行末
        # cursor_pos = QTextCursor.EndOfBlock #段末
        # cursor_pos = QTextCursor.EndOfWord #单词末
        # cursor_pos = QTextCursor.PreviousCharacter #上一个字符
        # cursor_pos = QTextCursor.PreviousBlock #上一个段落
        # cursor_pos = QTextCursor.PreviousWord #上一个单词
        # cursor_pos = QTextCursor.NextCharacter #下一个字符
        # cursor_pos = QTextCursor.NextBlock #下一个段落
        # cursor_pos = QTextCursor.NextWord #下一个单词
 
        # 判断自动补全后是否需要更改特定光标位置
        tc.movePosition(QTextCursor.EndOfWord)  # 先移动到单词尾部,避免错误
        if completion in self.specialCursorDict.keys():  # 存在特殊位置
            for i in range(self.specialCursorDict[completion]):
                tc.movePosition(QTextCursor.PreviousCharacter)
            self.setTextCursor(tc)
        else:  # 不存在特殊位置,移动到单词末尾
            tc.movePosition(QTextCursor.EndOfWord)
            self.setTextCursor(tc)
 
    # def focusInEvent(self, e):
    # 当edit获取焦点时激活completer
    # Open the widget where you are at in the edit
    #    if self._completer is not None:
    #        self._completer.setWidget(self)
    #    super(TextEdit, self).focusInEvent(e)
 
    def focusInEvent(self, e):
        # 当edit获取焦点时激活completer
        # Open the widget where you are at in the edit
        if self._completer is not None:
            self._completer.setWidget(self)
        super(TextEdit, self).focusInEvent(e)
 
    def dealTextChanged(self):
        '''
        内容改变处理信号处理
        '''
 
        '''下面是对keyPressEvent面对中文输入法输入时没反应的补充'''
        connect = self.toPlainText()
 
        class QKeyEvent:
            def key(self=None):
                return 0
 
            def text(self=None):
                return connect.split('\n')[-1].split(' ')[-1]
 
            def modifiers(self=None):
                return Qt.AltModifier
 
        self.keyPressEvent(type('QKeyEvent', (QKeyEvent,), {}))
 
    def getLastPhrase(self):
        '''
        获取最后一个词组(先以行分割,然后按空格分割词组)
        '''
        # 获取全部文本
        connect = self.toPlainText()
        # print(connect.split('\n')[-1].split(' '))
        lastPhrase = connect.split('\n')[-1].split(' ')[-1]
        return lastPhrase
 
    def keyPressEvent(self, e):
        '''
        按键按下事件
        @e::<PyQt5.QtGui.QKeyEvent object at 0x000001577FAE8048>
        e.text()输入的文本 , 像换行,tab这样的键是没有文本的
        e.key(),键盘上每个键都对应一个编码 如 换行 16777220,j 74
        '''
        isShortcut = False  # 判断是否是快捷键的标志
 
        # self._completer.popup().isVisible()) 判断 completer 是否弹出
        if self._completer is not None and self._completer.popup().isVisible():
            # print('Popup is up')
            # The following keys are forwarded by the completer to the widget.
            # 如果键入的是特殊键则忽略这次事件
            if e.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab):
                e.ignore()
                return
 
        # Ctrl + e 快捷键
        if e.key() == Qt.Key_E and e.modifiers() == Qt.ControlModifier:
            words = self.autoCompleteWords_list
            self._completer.setModel(QStringListModel(words))  # 设置数据
            isShortcut = True
        '''
        if e.key() == Qt.Key_Period:
            #This is how I will do the lookup functionality. Show when period is his, open the list of options.
            self.textCursor().insertText('.')
            self.moveCursor(QtGui.QTextCursor.PreviousWord)
            self.moveCursor(QtGui.QTextCursor.PreviousWord, QtGui.QTextCursor.KeepAnchor)
            dict_key = self.textCursor().selectedText().upper()
            #print('Dict Key' , dict_key)
            self.moveCursor(QtGui.QTextCursor.NextWord)
            self.moveCursor(QtGui.QTextCursor.NextWord)
            #print(dict_key)
            words = self.searchWords_dict[dict_key]
            self._completer.setModel(QStringListModel(words, self._completer))
            isShortcut = True
        '''
        # 当不存在关联的 completer 以及 当前键不是快捷键的时候执行父操作
        if (self._completer is None or not isShortcut) and e.key() != 0:
            # Do not process the shortcut when we have a completer.
            super(TextEdit, self).keyPressEvent(e)
 
        # 当当不存在关联的 completer 或者 有修饰符(ctrl或shift)和输入字符为空时 , 直接返回不进行任何操作
        ctrlOrShift = e.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier)  # 是ctrl或shift这样的修饰词
        if self._completer is None or (ctrlOrShift and len(e.text()) == 0):
            return
 
        # eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="
        eow = ''
        # 有修饰符 但 不是ctrl 或者 shift,例如alt出现 hasModifier 就为True
        hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift  # 判断是否有ctrl与shift外的修饰符
 
        lastPhrase = self.getLastPhrase()  # 当前出现的单词
        self.completion_prefix = lastPhrase
 
        # 限制最少输入俩个字符后才进行匹配 , 且不满足条件自动关闭界面
        # 不是快捷键,同时满足(没有修饰符 或者 文本为空 或者 输入字符少于2 或者 输入文本最后以eow中一个字符结尾)
        if not isShortcut and (len(e.text()) == 0 or len(lastPhrase) < 2):
            self._completer.popup().hide()
            return
        # not isShortcut 确保快捷键可以操作显示自动补全窗口
        # if not isShortcut and (hasModifier or len(e.text()) == 0 or len(lastPhrase) < 2 or e.text()[-1] in eow):
        # self._completer.popup().hide()
        # return
 
        # 选中第一项
        if lastPhrase != self._completer.completionPrefix():
            # Puts the Prefix of the word youre typing into the Prefix
            self._completer.setCompletionPrefix(lastPhrase)
            self._completer.popup().setCurrentIndex(  # QCompleter.popup().setCurrentIndex 设置选中项
                self._completer.completionModel().index(0,
                                                        0))  # QCompleter.completionModel() 返回QCompleter模型。 QCompleter模型是一个只读列表模型,它包含当前QCompleter前缀的所有可能匹配项。
 
        cr = self.cursorRect()
        # 设置 completer 尺寸
        cr.setWidth(self._completer.popup().sizeHintForColumn(
            0) + self._completer.popup().verticalScrollBar().sizeHint().width())
        self._completer.complete(cr)

源文地址:https://blog.csdn.net/cy19890616/article/details/133671794

基本步骤:

QT- QLineEdite设置自动补全功能,并修改自动补全的样式_completer->popup()设置样式-CSDN博客

 // 创建一个字符串列表模型
    QStringListModel model;
 
    // 设置模型的自动补全列表
    QStringList auto_complete_list{"apple", "banana", "cherry", "durian"};
    model.setStringList(auto_complete_list);
 
    // 创建一个自动补全器并设置模型
    QCompleter completer;
    completer.setModel(&model);
 
    // 设置自动补全样式为下拉列表
    completer.setCompletionMode(QCompleter::PopupCompletion);
 
    // 设置自动补全的样式表
    completer.popup()->setStyleSheet("QListView {"
                                     "background-color: lightgray;"
                                     "color: black;"
                                     "selection-background-color: darkgray;"
                                     "}");
 
    QLineEdit line_edit;

line_edit.setCompleter(&completer);

#对于对应输入的lineedit控件增加补全设置


                        
原文链接:https://blog.csdn.net/u013083044/article/details/132233911

文本变动触发槽函数

self.ui_1.LineEdit_1.textChanged.connect(self.fuc_1)

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值