PyQt5 QCompleter, как очистить QLineEdit после того, как текст автозаполнения был выбран - PullRequest
1 голос
/ 25 января 2020

Как очистить текстовое поле (QLineEdit) после того, как текст автозаполнения был выбран с помощью QCompleter? - Ничто не работает для меня.

Ниже приведен более простой пример моего кода: это простое консольное приложение «эхо», которое получает текстовые команды из QLineEdit (текстовое поле ввода) и записывает его в QTextBrowser (текст вывода) коробка). После того, как пользователь нажал клавишу ВВОД в текстовом поле ввода, его текст должен быть добавлен в текстовое поле вывода, а текстовое поле ввода должно быть очищено (чтобы быть готовым к следующей команде).

Когда ввод нового текста, которого нет в параметрах автоматического завершения, все работает хорошо: текст добавляется в текстовое поле вывода и очищается из текстового поля ввода. Однако, когда пользователь выбирает один из параметров автозаполнения (используя стрелки вниз / вверх) и затем нажимает клавишу ВВОД, текст добавляется в текстовое поле вывода, но не удаляется из текстового поля ввода ...

В обоих случаях вызывается моя функция обратного вызова (функция триггера), которая должна очистить текстовое поле ввода, используя:

self.consoleCommandLineEdit.clear()

, но когда текст автозавершения выбран ENTER, текстовое поле ввода не очищается ... Текст добавляется правильно в текстовое поле вывода, поэтому моя функция обратного вызова вызывается правильно. Похоже, что Completer заполняет мое текстовое поле после того, как я его очистил ... Как я могу отключить это поведение и убедиться, что текстовое поле ввода очищается? я могу удалить это ??

Ниже приведен весь пример. Вы можете попробовать это, набрав 'zzz' или любой другой текст, которого нет в списке автозаполнений, и нажмите клавишу ВВОД, а затем попробуйте набрать 'a', затем go вниз с клавиатуры на 'aaa1' (или любой другой на параметры автозаполнения) и нажмите ENTER. Вы увидите, что текстовое поле ввода не очищается в этом случае.

import sys
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import (
    QApplication,
    QWidget,
    QMainWindow,
    QVBoxLayout,
    QLineEdit,
    QTextBrowser,
    QCompleter,
)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setWindowTitle("console")
        self.setGeometry(10, 50, 500, 800)

        # Create text box for input
        self.consoleCommandLineEdit = QLineEdit()
        self.consoleCommandLineEdit.setFixedHeight(25)
        self.consoleCommandLineEdit.editingFinished.connect(self.gotConsoleCommand)

        self.model = QStandardItemModel()
        self.model.appendRow(QStandardItem('aaa1'))
        self.model.appendRow(QStandardItem('aaa2'))
        self.model.appendRow(QStandardItem('aaa3'))
        completer = QCompleter(self.model, self)
        self.consoleCommandLineEdit.setCompleter(completer)

        # Create text box for output
        self.consoleViewer = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap)

        widget = QWidget()
        self.setCentralWidget(widget)
        vlay = QVBoxLayout(widget)
        vlay.addWidget(self.consoleCommandLineEdit)
        vlay.addWidget(self.consoleViewer)

    def gotConsoleCommand(self):
        cmd = self.consoleCommandLineEdit.text()
        self.consoleCommandLineEdit.clear()
        self.consoleViewer.append(cmd)  # add cmd to output box


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

1 Ответ

1 голос
/ 26 января 2020

Проблема в том, что задачей QCompleter является завершение текста QLineEdit, и это то, что он делает, я подробно объясняю, что происходит: пользователь выбирает одну из опций всплывающего окна QCompleter, затем нажимает клавиша ввода. Это заставляет всплывающее окно закрываться, но также отправляет событие клавиши ввода в QLineEdit, вызывая передачу сигнала editFinished, ваш код удаляет текст, но затем QCompleter добавляет выбранный текст.

Решение состоит в том, что после добавления этого текста вы должны очистить, используя QTimer и активированный сигнал QCompleter:

    # ...
    completer = QCompleter(self.model, self)
    <b>completer.activated.connect(self.onActivated)</b>
    # ...

<b>def onActivated(self):
    QTimer.singleShot(0, self.consoleCommandLineEdit.clear)</b>
...