Pelco KBD300A 模拟器:06.用 PyQt5 实现 1:1 像素级完美复刻 Pelco KBD300A 键盘

第 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 协议发送。

二、关键代码

下面摘取关键片段,便于直接对照与复用。

样式生成函数
def btn_style_template(bg_color, border_color, font_px, radius_px, border_w=4):
    return f"""
        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);
        }}
    """
创建数字按键时的动态标记
# 在构建数字键时
if ch.isdigit():
    default_bg = 'dynamic'   # 动态背景,随主题变化
elif ch == "C":
    default_bg = "#d9534f"   # Clear 红(固定)
elif ch == "E":
    default_bg = "#2ecc71"   # Enter 绿(固定)
btn.default_bg = default_bg

# 初始样式
initial_bg = THEMES['current']['BTN_BG'] if default_bg == 'dynamic' else default_bg
btn.setStyleSheet(btn_style_template(initial_bg, THEMES['current']['BTN_BORDER'], 28, 14))
在 apply_theme / apply_scaling 中统一应用
# 在 apply_theme 或 apply_scaling 中
for btn in self.num_buttons:
    if getattr(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 呼吸闪烁
class AnimatedLCD(QtWidgets.QLCDNumber):
    def __init__(self, digits=4, parent=None):
        super().__init__(digits, parent)
        self._font_px = 28
        self.opacity = 1.0
        self.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)

    def flicker(self):
        self.opacity = 0.75 if self.opacity == 1.0 else 1.0
        self._apply_theme()
RealJoystick 核心回调
class RealJoystick(QtWidgets.QWidget):
    pan_tilt_changed = QtCore.pyqtSignal(int, int)
    def mouseMoveEvent(self, e):
        if self.dragging:
            vec = e.pos() - self.center
            length = (vec.x() ** 2 + vec.y() ** 2) ** 0.5
            if length > self._max_radius and length != 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

安装命令:

pip install PyQt5==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 循环、条件判断、变量、延时、注释
  • 一键录制 → 自动生成可读脚本 → 无限次回放
  • 带语法高亮、单步调试、断点功能
    上一篇 目录 下一篇
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值