PyQt5 QCompleter 如何在选择自动完成文本后清除 QLineEdit
PyQt5 QCompleter how to clear the QLineEdit after auto-completion text was selected
如何在使用 QCompleter 选择自动完成文本后清除文本框 (QLineEdit)? - 什么都不适合我。
下面是我的代码的一个更简单的示例:它是一个简单的 "echo" 控制台应用程序,它从 QLineEdit(输入文本框)获取文本命令并将其写入 QTextBrowser(输出文本框)。一旦用户在输入文本框上按下 ENTER,该文本框的文本应该被添加到输出文本框,输入文本框应该被清除(为下一个命令做好准备)。
当输入不在自动完成选项中的新文本时,一切正常:文本被添加到输出文本框中并从输入文本框中清除。但是,当用户从自动完成选项中选择一个选项(使用 down/up 箭头)然后按 ENTER 时,文本将添加到输出文本框中,但不会从输入文本框中删除。 ..
两种情况都调用我的回调函数(触发函数),它应该清除输入文本框,使用:
self.consoleCommandLineEdit.clear()
但是当回车选择自动完成文本时,输入文本框没有被清除...
文本已正确添加到输出文本框中,因此我的回调函数被正确调用。
看起来完成者在我清除它后正在填充我的文本框......
如何禁用此行为并确保清除输入文本框?我可以删除它吗??
下面是整个例子。您可以通过键入 '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_())
问题是 QCompleter 的任务是完成 QLineEdit 的文本,这就是它正在做的,我详细解释发生了什么:用户选择 QCompleter 的弹出选项之一,然后按回车键,这会导致弹出窗口关闭,但也会将回车键的事件发送到 QLineEdit,导致发出 editingFinished 信号,您的代码删除了文本,但 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>
如何在使用 QCompleter 选择自动完成文本后清除文本框 (QLineEdit)? - 什么都不适合我。
下面是我的代码的一个更简单的示例:它是一个简单的 "echo" 控制台应用程序,它从 QLineEdit(输入文本框)获取文本命令并将其写入 QTextBrowser(输出文本框)。一旦用户在输入文本框上按下 ENTER,该文本框的文本应该被添加到输出文本框,输入文本框应该被清除(为下一个命令做好准备)。
当输入不在自动完成选项中的新文本时,一切正常:文本被添加到输出文本框中并从输入文本框中清除。但是,当用户从自动完成选项中选择一个选项(使用 down/up 箭头)然后按 ENTER 时,文本将添加到输出文本框中,但不会从输入文本框中删除。 ..
两种情况都调用我的回调函数(触发函数),它应该清除输入文本框,使用:
self.consoleCommandLineEdit.clear()
但是当回车选择自动完成文本时,输入文本框没有被清除... 文本已正确添加到输出文本框中,因此我的回调函数被正确调用。 看起来完成者在我清除它后正在填充我的文本框...... 如何禁用此行为并确保清除输入文本框?我可以删除它吗??
下面是整个例子。您可以通过键入 '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_())
问题是 QCompleter 的任务是完成 QLineEdit 的文本,这就是它正在做的,我详细解释发生了什么:用户选择 QCompleter 的弹出选项之一,然后按回车键,这会导致弹出窗口关闭,但也会将回车键的事件发送到 QLineEdit,导致发出 editingFinished 信号,您的代码删除了文本,但 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>