Проблема с фокусом QPlainTextEdit и QCompleter

Я прочитал документы QCompleter (https://doc.qt.io/qt-5/qcompleter.html) и попытался реализовать QCompleter для QPlainTextEdit.

Теперь у меня это работает так:

Проблема с фокусом QPlainTextEdit и QCompleter

Но проблема в том, что если вы начинаете писать слово из списка, созданного с помощью keyword.kwlist, оно фокусируется на всплывающем окне, которое появляется под курсором, и не позволяет мне продолжать вводить текст.

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

Я попытался установить фокус на self.editor, но это не сработало. Мне нужна помощь с этим и с положением всплывающего окна. Прямо сейчас это как бы блокирует просмотр слова.

Он должен функционировать следующим образом:

Проблема с фокусом QPlainTextEdit и QCompleter

но это работает только с 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_())

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

eyllanesc 18.08.2018 23:21

Я добавил гифку, которая это объясняет. В любом случае я постараюсь объяснить это получше. Когда вы пишете в QLineEdit, когда он предлагает слово, вы все равно можете продолжать печатать, но в моей реализации он застрял, и вам нужно выбрать слово, чтобы продолжить ввод.

user8513021 19.08.2018 00:23

Нет, с другой стороны, мой вопрос был в том, что вы указываете, что конвертируете код из C++ в python, что это за код?

eyllanesc 19.08.2018 00:24

Код в разделе "Основное использование": doc.qt.io/qt-5/qcompleter.html#details

user8513021 19.08.2018 00:27
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
692
0

Другие вопросы по теме