PySide2:QListWidget 弹出代码完成和焦点管理问题

问题描述 投票:0回答:1

我正在尝试使用 PySide2 在 QPlainTextEdit 内构建一个类似 IntelliSense 的代码完成系统。但是,我面临焦点管理和 QListWidget 弹出时隐藏的问题。目标是在用户键入时显示弹出窗口,允许他们在弹出窗口可见时继续在文本编辑器中键入内容,然后在需要时隐藏弹出窗口(例如,按 Escape 键或将光标移开)。

以下是我面临的主要问题:

焦点问题:我使用 self.completer_list.setFocusPolicy(Qt.NoFocus) 来防止弹出窗口获取焦点,但是当使用 Qt.Popup 时,焦点仍然转移到 QListWidget,并且程序的其余部分变得无响应,直到我与弹出窗口交互。

弹出窗口隐藏问题:我使用 self.completer_list.hide() 来隐藏弹出窗口,但它并不总是正确隐藏,或者在单击外部或光标移动时响应不佳。

我的代码可能做错了什么?

这是我的代码的一部分:

self.temp_completer_list = ["for", "while", "if", "else", "elif", "def",
                           "class", "import", "from", "return", "try", "except", "finally"]
    self.completer_list = QListWidget()
    self.completer_list.addItems(self.temp_completer_list)
    self.completer_list.setWindowFlag(Qt.Popup)
    self.completer_list.hide()
    self.textChanged.connect(self.show_completer_list)

def show_completer_list(self):
    """CURSOR TO POPUP"""
    cursor = self.textCursor()
    pos = self.cursorRect(cursor).bottomRight()
    global_pos = self.mapToGlobal(pos)
    self.completer_list.move(global_pos)
    self.completer_list.show()
    self.completer_list.setFocusPolicy(Qt.NoFocus)
python-3.x autocomplete pyside2 qcompleter
1个回答
0
投票

我是用“绝地武士”来做到这一点的:

 # QCompleter oluştur
    self.completer = QCompleter(self)
    self.completer.setCompletionMode(QCompleter.PopupCompletion)
    self.completer.setWidget(self)

    # Dinamik olarak güncellenecek model
    self.model = QStringListModel()
    self.completer.setModel(self.model)

    # İmleç pozisyonuna göre tamamlama popup'ını göster
    self.textChanged.connect(self.show_completer)

    # Completer'den bir öneri seçildiğinde, insert_completion fonksiyonunu çağır.
    self.completer.activated.connect(self.insert_completion)

def show_completer(self):
    """Tamamlama popup'ını göster"""
    cursor = self.textCursor()
    cursor.select(cursor.WordUnderCursor)
    current_code = self.toPlainText()  # Şu anki metni al
    line, col = cursor.blockNumber() + 1, cursor.columnNumber()  # Jedi'ye göndermek için pozisyonu al

    # Jedi'yi kullanarak tamamlama önerileri al
    script = jedi.Script(current_code)
    completions = script.complete(line, col)  # Satır ve sütun numarasını burada kullanıyoruz

    # Eğer tamamlama önerileri varsa, popup'ı göster
    if completions:
        completion_list = [comp.name for comp in completions]  # Önerileri listeye dönüştür
        self.model.setStringList(completion_list)

        rect = self.cursorRect()
        rect.setX(rect.x() + 35)  # Popup'ı 2 birim sağa kaydırıyoruz
        rect.setWidth(self.completer.popup().sizeHintForColumn(0) + 100)  # Popup genişliği

        # Popup için opaklık ayarı yapıyoruz
        opacity_effect = QGraphicsOpacityEffect(self.completer.popup())
        opacity_effect.setOpacity(0.9)  # %90 opaklık
        self.completer.popup().setGraphicsEffect(opacity_effect)

        self.completer.complete(rect)  # Popup'ı göster
    else:
        self.completer.popup().hide()  # Eğer öneri yoksa popup'ı gizle

def keyPressEvent(self, event):
    cursor = self.textCursor()

    if self.completer.popup().isVisible():
        if event.key() in (Qt.Key_Enter, Qt.Key_Return):
            selected_item = self.completer.popup().currentIndex().data()
            if selected_item:
                self.insert_completion(selected_item)
            self.completer.popup().hide()
            return  # Varsayılan işleyiciyi engelle
        elif event.key() == Qt.Key_Space or event.key() == Qt.Key_Escape:
            self.completer.popup().hide()
            return
© www.soinside.com 2019 - 2024. All rights reserved.