You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PyQt5中QLineEdit的editingFinished信号绑定函数执行两次并导致程序退出的问题排查与解决

PyQt5 QLineEdit editingFinished触发两次+程序意外退出的问题解决

我之前在PyQt5开发QDialog界面时,也碰到过一模一样的问题:给QLineEdit绑定editingFinished信号到自定义search函数,按下回车后函数执行两次,还会直接退出程序。结合你描述的场景,我来拆解下原因和解决方案:

问题根源

你的QDialog里应该用了QDialogButtonBox,并且把它的accepted信号绑定到了Dialog.accept()。而QDialogButtonBox的OK按钮默认是默认按钮(按钮外有蓝色边框标记),按下回车键时,系统会同时触发两个事件:

  1. QLineEdit的editingFinished信号(因为输入结束按下回车)
  2. 默认OK按钮的点击事件,进而触发accepted信号,调用Dialog.accept()让对话框关闭退出

这就导致search函数被执行一次,对话框关闭的流程又连带触发了一次editingFinished,最终出现两次输出+程序退出的情况。

解决方案

针对这个场景,有几个可行的解决办法:

方案1:禁用QDialogButtonBox的默认按钮回车响应

可以修改OK按钮的默认属性,让它不再响应回车键:

button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
# 获取OK按钮并取消其默认按钮状态
ok_button = button_box.button(QDialogButtonBox.Ok)
ok_button.setDefault(False)
# 再绑定信号
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)

方案2:自定义回车触发按钮,替代默认OK按钮的功能

如果不需要默认的OK按钮,可以添加一个自定义按钮,专门处理回车触发,同时保留QLineEdit的editingFinished信号:

# 创建自定义按钮
custom_btn = QPushButton("搜索")
custom_btn.clicked.connect(lambda: self.search(self.lineEdit.text()))
# 设置按钮为默认按钮,让回车触发它
custom_btn.setDefault(True)

方案3:在search函数中添加防抖逻辑

如果必须保留原有结构,可以在search函数里加一个执行标记,确保同一时间只执行一次:

def __init__(self):
    # 初始化标记
    self.search_executed = False

def search(self, a):
    if self.search_executed:
        return
    self.search_executed = True
    print(f"hello world {a}")
    # 可以根据需求重置标记
    # self.search_executed = False

核心代码参考

你给出的核心绑定代码本身是没问题的,问题出在对话框的默认按钮行为上:

#### IMPORTANT PART ####
a = "MY NAME"
self.lineEdit.editingFinished.connect(lambda x=a: self.search(x))
### IMPORTANT PART ###
def search(self, a):
    print(f"hello world {a}")

内容的提问来源于stack exchange,提问作者urie

火山引擎 最新活动