1

使用 QCompleter 选择自动完成文本后,如何清除文本框 (QLineEdit)?- 没有什么对我有用。

下面是我的代码的一个更简单的示例:它是一个简单的“回显”控制台应用程序,它从 QLineEdit(输入文本框)获取文本命令并将其写入 QTextBrowser(输出文本框)。一旦用户在输入文本框上按下 ENTER,该文本应该被添加到输出文本框中,并且输入文本框应该被清除(为下一个命令做好准备)。

输入不在自动完成选项中的新文本时,一切正常:文本被添加到输出文本框中并从输入文本框中清除。但是,当用户从自动完成选项中选择一个选项(使用向下/向上箭头)然后按 ENTER 时,文本将添加到输出文本框中,但不会从输入文本框中删除...

这两种情况都调用我的回调函数(触发函数),它应该清除输入文本框,使用:

self.consoleCommandLineEdit.clear()

但是当通过ENTER选择自动完成文本时,输入文本框不会被清除......文本被正确添加到输出文本框中,所以我的回调函数被正确调用。在我清除它之后,完成器似乎正在填充我的文本框......如何禁用此行为并确保输入文本框被清除?我可以删除它吗?

下面是整个例子。您可以尝试通过键入“zzz”或任何其他不在自动完成列表中的文本并按 ENTER,然后尝试键入“a”,然后使用键盘向下输入“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_())
4

1 回答 1

2

问题是 QCompleter 的任务是完成 QLineEdit 的文本,这就是它正在做的事情,我详细解释了发生了什么:用户选择 QCompleter 的弹出选项之一,然后按回车键, 这会导致弹出窗口关闭,但也会将 enter 键的事件发送到 QLineEdit,从而导致发出 editingFinished 信号,您的代码会删除文本,但随后 QCompleter 添加选定的文本。

解决方案是添加该文本后,您必须使用 QTimer 和激活的 QCompleter 信号进行清理:

    # ...
    completer = QCompleter(self.model, self)
    completer.activated.connect(self.onActivated)
    # ...

def onActivated(self):
    QTimer.singleShot(0, self.consoleCommandLineEdit.clear)
于 2020-01-25T21:36:41.600 回答