我正在尝试使用 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)
我是用“绝地武士”来做到这一点的:
# 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