如何阻止父对话框响应子QMessageBox触发的回车按键信号?
解决QMessageBox关闭时回车触发重复登录的问题
当前实现中,登录对话框通过重写keyReleaseEvent监听回车键,触发enterPressed信号执行登录逻辑。但当登录失败弹出QMessageBox后,按下回车键关闭该消息框时,回车事件会向上传递到登录对话框的keyReleaseEvent,再次触发登录操作,导致QMessageBox重复弹出。
原因分析
模态的QMessageBox关闭时,其键盘事件会沿父窗口链传递,触发登录对话框的keyReleaseEvent,进而重复执行登录逻辑。
解决方案
方案1:绑定输入框的回车信号(推荐)
放弃全局窗口的键盘事件监听,直接给ID和密码输入框的returnPressed信号绑定登录逻辑,仅在输入框内按下回车时触发登录,避免消息框关闭时的误触发。
修改后的代码:
# 移除全局的enterPressed信号定义,无需再使用 def connect_ui(self): self.login_button.clicked.connect(self._login) # 给两个输入框绑定回车触发登录 self.ID_line_edit.returnPressed.connect(self._login) self.password_line_edit.returnPressed.connect(self._login) return def _login(self): id_value = self.ID_line_edit.text() password_value = self.password_line_edit.text() user_data = self.server_data.get(id_value) if user_data: if user_data["password"] == password_value: self.close() self.parent.login_button.hide() self.parent.profile_button.show() cacher.save(self.server_data) return else: QtWidgets.QMessageBox.warning(self,"Login Error","Invalid password!") return else: QtWidgets.QMessageBox.warning(self,"Login Error","Invalid ID!") return # 移除全局的keyReleaseEvent重写
方案2:保留全局事件但增加焦点判断
如果需要保留全局键盘事件监听,可增加判断:仅当焦点在输入框内时,才触发登录信号。
修改后的keyReleaseEvent:
enterPressed = QtCore.Signal() def connect_ui(self): self.login_button.clicked.connect(lambda *args: self._login()) self.enterPressed.connect(lambda *args: self._login()) return def _login(self): # 原_login逻辑不变 id_value = self.ID_line_edit.text() password_value = self.password_line_edit.text() user_data = self.server_data.get(id_value) if user_data: if user_data["password"] == password_value: self.close() self.parent.login_button.hide() self.parent.profile_button.show() cacher.save(self.server_data) return else: QtWidgets.QMessageBox.warning(self,"Login Error","Invalid password!") return else: QtWidgets.QMessageBox.warning(self,"Login Error","Invalid ID!") return def keyReleaseEvent(self,event): # 检查当前焦点是否在输入框内 focused_widget = QtWidgets.QApplication.focusWidget() if (event.key() == QtCore.Qt.Key_Return and focused_widget in [self.ID_line_edit, self.password_line_edit]): self.enterPressed.emit() super(login_dialog, self).keyReleaseEvent(event)
内容的提问来源于stack exchange,提问作者pien axo
相关产品推荐
相关产品推荐

