Я прочитал документы QCompleter (https://doc.qt.io/qt-5/qcompleter.html) и попытался реализовать QCompleter для QPlainTextEdit.
Теперь у меня это работает так:
Но проблема в том, что если вы начинаете писать слово из списка, созданного с помощью keyword.kwlist, оно фокусируется на всплывающем окне, которое появляется под курсором, и не позволяет мне продолжать вводить текст.
Но при преобразовании кода из C++ в python на странице документации QCompleter я все равно мог печатать, даже если он предлагал мне подборку слов ниже.
Я попытался установить фокус на self.editor, но это не сработало. Мне нужна помощь с этим и с положением всплывающего окна. Прямо сейчас это как бы блокирует просмотр слова.
Он должен функционировать следующим образом:
но это работает только с QLineEdit.
from PyQt5.QtWidgets import QCompleter, QPlainTextEdit, QApplication, QWidget, QHBoxLayout
import sys
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QTextCursor, QFont, QTextOption
import keyword
class Completer(QCompleter):
insertText = pyqtSignal(str)
def __init__(self, myKeywords=None, parent=None):
myKeywords = keyword.kwlist
QCompleter.__init__(self, myKeywords, parent)
self.activated.connect(self.changeCompletion)
def changeCompletion(self, completion):
if completion.find("(") != -1:
completion = completion[:completion.find("(")]
print(completion)
print("completion is " + str(completion))
self.insertText.emit(completion + " ")
self.popup().hide()
class MyTextEdit(QWidget):
def __init__(self, *args):
super().__init__(*args)
font = QFont()
font.setPointSize(12)
self.editor = QPlainTextEdit()
self.setFont(font)
self.completer = None
self.hbox = QHBoxLayout(self)
self.editor.textChanged.connect(self.complete)
self.hbox.addWidget(self.editor)
def setCompleter(self, completer):
if self.completer:
print("completer is: " + str(completer))
self.disconnect()
if not completer:
print("completer is: " + str(completer))
return
completer.setWidget(self)
completer.setCompletionMode(QCompleter.PopupCompletion)
completer.setCaseSensitivity(Qt.CaseInsensitive)
self.completer = completer
self.completer.insertText.connect(self.insertCompletion)
def insertCompletion(self, completion):
tc = self.editor.textCursor()
extra = (len(completion) - len(self.completer.completionPrefix()))
tc.movePosition(QTextCursor.Left)
tc.movePosition(QTextCursor.EndOfWord)
tc.insertText(completion[-extra:])
self.editor.setTextCursor(tc)
def textUnderCursor(self):
tc = self.editor.textCursor()
tc.select(QTextCursor.WordUnderCursor)
return tc.selectedText()
def complete(self):
completionPrefix = self.textUnderCursor()
print("completion prefix is: " + str(completionPrefix))
self.completer.setCompletionPrefix(completionPrefix)
popup = self.completer.popup()
popup.setCurrentIndex(
self.completer.completionModel().index(0, 0))
cr = self.editor.cursorRect()
cr.setWidth(
self.completer.popup().sizeHintForColumn(0) + self.completer.popup().verticalScrollBar().sizeHint().width())
self.completer.complete(cr)
if __name__ == "__main__":
app = QApplication(sys.argv)
completer = Completer()
te = MyTextEdit()
te.setCompleter(completer)
te.show()
sys.exit(app.exec_())
Я добавил гифку, которая это объясняет. В любом случае я постараюсь объяснить это получше. Когда вы пишете в QLineEdit, когда он предлагает слово, вы все равно можете продолжать печатать, но в моей реализации он застрял, и вам нужно выбрать слово, чтобы продолжить ввод.
Нет, с другой стороны, мой вопрос был в том, что вы указываете, что конвертируете код из C++ в python, что это за код?
Код в разделе "Основное использование": doc.qt.io/qt-5/qcompleter.html#details






Не могли бы вы объяснить следующее: Но при преобразовании кода с C++ в python на странице документации QCompleter я все равно мог печатать, даже если он предлагал мне выбор слов ниже?