You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt6登录窗口keyboard库Enter键误触发异常求助

PyQt6登录窗口Enter键触发问题解决方案

问题描述

开发PyQt6登录窗口时,希望用户无需点击登录按钮,仅通过Enter键完成登录,使用keyboard库的on_press_key("enter")绑定登录逻辑后,发现从终端按Enter键运行Python程序时,该按键会被keyboard捕获并触发登录逻辑,导致程序未正常启动就报错。需要忽略程序启动时的首个Enter输入,且无法更换其他按键。

原代码存在的问题

  1. 回调函数传递错误:keyboard.on_press_key("enter",self.enter_pressed())中,self.enter_pressed()是直接执行方法并返回结果,而非传递回调函数引用,正确写法应为self.enter_pressed(不带括号)。
  2. 全局监听副作用: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:31:32