PyQt6登录窗口keyboard库Enter键误触发异常求助
PyQt6登录窗口Enter键触发问题解决方案
问题描述
开发PyQt6登录窗口时,希望用户无需点击登录按钮,仅通过Enter键完成登录,使用keyboard库的on_press_key("enter")绑定登录逻辑后,发现从终端按Enter键运行Python程序时,该按键会被keyboard捕获并触发登录逻辑,导致程序未正常启动就报错。需要忽略程序启动时的首个Enter输入,且无法更换其他按键。
原代码存在的问题
- 回调函数传递错误:
keyboard.on_press_key("enter",self.enter_pressed())中,self.enter_pressed()是直接执行方法并返回结果,而非传递回调函数引用,正确写法应为self.enter_pressed(不带括号)。 - 全局监听副作用:
keyboard库是全局键盘监听,会捕获终端中启动程序时按下的Enter键,导致提前触发登录逻辑。
解决方案
方案一:修复keyboard库使用并忽略首个按键
通过添加标志位,首次触发Enter键时跳过登录逻辑,后续正常响应:
from PyQt6.QtCore import * from PyQt6.QtGui import * from PyQt6.QtWidgets import * import mysql.connector import sys import keyboard import main_window class login_window(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Wochenbericht") self.setWindowIcon(QIcon(r"src/schreibfeder.png")) self.setObjectName("login_window") self.setMinimumSize(300,300) self.setMaximumSize(300,300) main_layout = QGridLayout() login_fields = QVBoxLayout() main_layout.addLayout(login_fields,0,0) button_fields = QHBoxLayout() main_layout.addLayout(button_fields,1,0) self.setLayout(main_layout) # FIELDS FOR THE LOGIN self.username = QLineEdit(self) self.username.setObjectName("username_field") self.password = QLineEdit(self) self.password.setEchoMode(QLineEdit.EchoMode.Password) self.password.setObjectName("password_field") login_fields.addWidget(self.username) login_fields.addWidget(self.password) # BUTTONS FOR THE LOGIN login_btn = QPushButton(self) login_btn.setText("Login") login_btn.clicked.connect(self.check_in) cancel_btn = QPushButton(self) cancel_btn.setText("Abbrechen") cancel_btn.clicked.connect(self.cancel) button_fields.addWidget(login_btn) button_fields.addWidget(cancel_btn) # 添加标志位,标记是否是首次触发Enter键 self.first_enter = True # 正确传递回调函数(不带括号) keyboard.on_press_key("enter", self.enter_pressed) def cancel(self) : self.close() def check_in(self): username = self.username.text() key = self.password.text() try: connector = mysql.connector.connect( host = 'localhost', user = username, password = key, database = 'berichte' ) self.close() self.tb_window = main_window.main_window(connector) self.tb_window.show() except mysql.connector.Error as e : if e.errno == 1045: warning_message = QMessageBox(self) warning_message.setText("Anmeldung fehlgeschlagen: Nutzername oder Passwort stimmen nicht überein") warning_message.show() else : print(f"Error: {e}") def enter_pressed(self, event): # 首次触发时跳过,之后正常执行登录 if self.first_enter: self.first_enter = False return self.check_in() if __name__ == "__main__": app = QApplication(sys.argv) window = login_window() window.show() sys.exit(app.exec())
方案二:使用PyQt原生方式处理Enter键(推荐)
无需依赖keyboard库,通过PyQt的原生机制处理Enter键,仅在登录窗口聚焦时响应,避免全局监听的副作用:
方法A:设置登录按钮为默认按钮
将登录按钮设为窗口默认按钮,用户按下Enter键时自动触发按钮点击事件:
# 在初始化登录按钮的代码中添加 login_btn.setDefault(True)
只需在原代码中给login_btn加上这一行,即可实现Enter键触发登录,且不会捕获终端的按键。
方法B:重写keyPressEvent事件
在窗口类中重写键盘按下事件,仅当窗口处于激活状态时响应Enter键:
class login_window(QWidget): # ... 其他代码保持不变 ... def keyPressEvent(self, event): if event.key() == Qt.Key.Key_Return or event.key() == Qt.Key.Key_Enter: self.check_in() super().keyPressEvent(event)
这种方式同样仅在窗口获得焦点时响应Enter键,不会影响终端输入。
内容的提问来源于stack exchange,提问作者dinglewringle52
相关产品推荐
相关产品推荐

