第 6 篇:用 PyQt5 实现 1:1 像素级完美复刻 Pelco KBD300A 键盘
真正的“永不磨损的实体键盘”诞生,Windows 7 完美运行,视觉与手感 99.9% 还原
发布时间:2025 年 12 月
一、背景与进化历程
在前五篇文章中,我们已经完成了从协议解析 → 链式调用类 → 基础 GUI的逐步演进。
今天正式发布终极形态:
一台可以直接替代真实 KBD300A 的软件键盘。
连最挑剔的老工程师把真机摆在旁边都分不出来哪个是真的。
核心特性:
- 像素级视觉还原:按钮圆角、边框、阴影与按下动画模拟实体键感。
- 摇杆高精度模拟:鼠标拖动产生
pan/tilt值,范围 (-127…127),自动回中。 - LCD 七段显示与呼吸闪烁:2800ms 周期的微弱呼吸效果,支持缩放。
- 响应式布局:基于基准窗口尺寸按比例缩放所有控件与字体。
- 主题切换:暗色与浅色主题,数字键(0–9)随主题动态变色;C/E 键保留固定强调色以便快速识别。
- 串口占位支持:可选
pyserial集成,保留发送/接收占位点,便于后续实现 Pelco 协议发送。
二、关键代码
下面摘取关键片段,便于直接对照与复用。
样式生成函数
defbtn_style_template(bg_color,border_color,font_px,radius_px,border_w=4):returnf""" QPushButton {{ background:{bg_color}; color:{THEMES['current']['TEXT_PRIMARY']}; font: bold{font_px}px 'Arial'; border:{border_w}px outset{border_color}; border-radius:{radius_px}px; }} QPushButton:hover {{ background:{THEMES['current']['ACCENT_SOFT']}; }} QPushButton:pressed {{ border-style: inset; background: rgba(255,255,255,0.02); }} QPushButton:disabled {{ color: rgba(200,200,200,0.4); background: rgba(255,255,255,0.02); }} """创建数字按键时的动态标记
# 在构建数字键时ifch.isdigit():default_bg='dynamic'# 动态背景,随主题变化elifch=="C":default_bg="#d9534f"# Clear 红(固定)elifch=="E":default_bg="#2ecc71"# Enter 绿(固定)btn.default_bg=default_bg# 初始样式initial_bg=THEMES['current']['BTN_BG']ifdefault_bg=='dynamic'elsedefault_bg btn.setStyleSheet(btn_style_template(initial_bg,THEMES['current']['BTN_BORDER'],28,14))在 apply_theme / apply_scaling 中统一应用
# 在 apply_theme 或 apply_scaling 中forbtninself.num_buttons:ifgetattr(btn,'default_bg',None)=='dynamic':bg=THEMES['current']['BTN_BG']else:bg=btn.default_bg btn.setStyleSheet(btn_style_template(bg,THEMES['current']['BTN_BORDER'],font_size_num,radius_num))AnimatedLCD 呼吸闪烁
classAnimatedLCD(QtWidgets.QLCDNumber):def__init__(self,digits=4,parent=None):super().__init__(digits,parent)self._font_px=28self.opacity=1.0self.timer=QtCore.QTimer(self)self.timer.timeout.connect(self.flicker)self.timer.start(2800)def_apply_theme(self):t=THEMES['current']style=f""" QLCDNumber {{ background:{t['LCD_BG']}; color:{t['ACCENT']}; border: 2px solid{t['LCD_BORDER']}; border-radius: 8px; padding: 6px; font: bold{self._font_px}px 'Consolas'; }} """self.setStyleSheet(style)defflicker(self):self.opacity=0.75ifself.opacity==1.0else1.0self._apply_theme()RealJoystick 核心回调
classRealJoystick(QtWidgets.QWidget):pan_tilt_changed=QtCore.pyqtSignal(int,int)defmouseMoveEvent(self,e):ifself.dragging:vec=e.pos()-self.center length=(vec.x()**2+vec.y()**2)**0.5iflength>self._max_radiusandlength!=0:scale=self._max_radius/length vec=QtCore.QPoint(int(vec.x()*scale),int(vec.y()*scale))self.pos=self.center+vec self.update()pan=int(vec.x()/self._max_radius*127)tilt=int(-vec.y()/self._max_radius*127)self.pan_tilt_changed.emit(pan,tilt)三、运行环境与要求
最低配置:
- 操作系统:Windows 7 SP1(32/64 位均可)
- Python:3.7.9
- 依赖库:
- PyQt5==5.15.2
- pyserial
安装命令:
pipinstallPyQt5==5.15.2 pyserial运行方式:
python KBD300A_main.py打包命令:
pyinstaller--clean--noconfirm KBD300A_main.spec打包版本文件:
# UTF-8 VSVersionInfo( ffi=FixedFileInfo( filevers=(1, 0, 0, 0), prodvers=(1, 0, 0, 0), mask=0x3f, flags=0x0, OS=0x40004, # Windows NT 32-bit fileType=0x1, subtype=0x0, date=(0, 0) ), kids=[ StringFileInfo([ StringTable( '080404b0', # 简体中文 [ StringStruct('CompanyName', '智码电子'), StringStruct('FileDescription', 'KBD300软键盘控制软件'), StringStruct('FileVersion', '1.0.0.0'), StringStruct('InternalName', 'kbd300_tool'), StringStruct('LegalCopyright', '版权所有 © 2025 我送炭你添花'), StringStruct('OriginalFilename', 'KBD300A_V1.0.exe'), StringStruct('ProductName', 'KBD300软键盘'), StringStruct('ProductVersion', '1.0.0.0') ] ) ]), VarFileInfo([ VarStruct('Translation', [0x0804, 1200]) ]) ] )双击运行,即刻出现一台永不磨损、永不掉键的 Pelco KBD300A!
四、运行界面
暗色主题:
浅色主题:
五、资源
源代码和打包后的exe文件,请点击(稍后上传)
六、下篇预告
下一篇(第 7 篇)将带来更强大的功能:
《内置完整宏脚本编辑器 + 实时解释器 + 无限长度 Pattern 录制与单步调试》
届时,这台“软件键盘”将拥有原装 KBD300A 永远不可能具备的超级大脑:
- 支持
for/while循环、条件判断、变量、延时、注释 - 一键录制 → 自动生成可读脚本 → 无限次回放
- 带语法高亮、单步调试、断点功能
上一篇目录下一篇