【项目复现】音效键盘SoundKeyboard的复现经验

作为写过点开源垃圾的学生,今天准备复现一款项目并尝试解析其中的代码。毕竟我太想进步了。

大家也可以试试复现我的一些垃圾:https://github.com/apcipotrain

源素材

我开发了按键盘就放音效的有声键盘,扣1笑面虎,扣2乌角鲨,扣Z键自刎归天_哔哩哔哩_bilibili

Github链接:https://github.com/PizzaDark/SoundKeyboard

下载

没想到卡住我的第一步,是下载!

原来"code"内部有玄机呀!

我们当然用git clone命令。

于是乎就下载好了,这是目前的文件夹。

复现

众所周知,一个项目最先看readme。

它提供了两套方法,那我们两套方法都操作一遍。

先操作方法二:(venv是virtual environment)

目前该路径就多出来了一个.venv的文件夹

现在运行python main.py

这个键盘是出来了,但是呢,没有声音!这个问题下面再说。

接着我们用run.bat文件试试能不能达到相同的效果。

没有问题,依然是在后面我们逐步拆解这个bat文件在干什么。

配置音频

走到这里我的注意力也下滑了,操作也变难了,然后墨迹了很久。

(于是我决定写一个项目,给它我自己的路径,能够输出目录树,毕竟要被自己的效率气晕嘞)

一直走到这里,我发现github上的源代码没有音频,原来网盘分享的是带了音频的代码。

然后逐个导入,我发现还是太麻烦,视频上写的是exe文件拖进去。所以我又生成了exe文件,操作如下:

现在下载好了,在SoundKeyboard\dist文件夹下面出现了SoundKeyboard.exe文件。

回过头来看,原来是导入音效包,选中文件夹就可以了,不是选择mp3文件,他会自己配对键盘对应的文件。

现在敲键盘,这音效跟tm三国杀一样。

证明我成功了。

代码

rule.json

文件大致如下。

键名是键盘按键,值是一个对象,包含文件名和状态值两个数据。

run.bat

这里面的注释很详细

:: 第一步:检查 Python 3.10+ 环境

:: 第二步:检查 Git 环境

:: 第三步:创建虚拟环境

:: 第四步:激活虚拟环境

:: 第五步:安装依赖

main.py

这是一个1k行出头的文件。

主要模块、类、函数:

===================== Win32 常量与结构 =====================23-184行

class KEYBDINPUT(ctypes.Structure):

class HARDWAREINPUT(ctypes.Structure):

class MOUSEINPUT(ctypes.Structure):

class INPUT_UNION(ctypes.Union):

class INPUT(ctypes.Structure):

def _make_key_input(vk, flags=0):

"""构造一个键盘 INPUT 结构"""

def do_send_input(inputs):

"""发送一组 INPUT"""

def simulate_keys(key, modifier_keys=None, target_hwnd=None):

"""在子线程中:恢复目标窗口焦点 → 发送按键 → 完成"""

===================== 键名规范化 =====================185-243行

def _build_key_map():

def normalize_key(name, scan_code=None):

def get_resource_path(relative_path):

"""获取资源文件的绝对路径(兼容开发环境和PyInstaller打包后的环境)"""

class KeySignal(QObject):

===================== 音频处理 =====================244-287行

def make_reversed_sound(filepath):

def make_octave_down_sound(filepath):

===================== 音频引擎 =====================288-448行

class AudioEngine:

def init(self):

def load_pack(self, pack_dir, overwrite_rules=True):

def reload_sounds(self):

def save_rules(self):

def _get_sound(self, key):

def toggle_caps(self):

def toggle_shift(self):

def _delayed_space_pause(self):

def play_key(self, key):

def release_key(self, key):

def load_performance_key(self, filepath):

===================== 按键捕获对话框 =====================449-507行

class KeyCaptureDialog(QDialog):

def init(self, parent=None):

def keyPressEvent(self, e): pass

def keyReleaseEvent(self, e): pass

def showEvent(self, e):

def hideEvent(self, e):

def _on_key(self, e):

class ReadOnlyItem(QTableWidgetItem):

def init(self, text=""):

===================== 设置面板 =====================508-777行

class CustomSettingsUI(QWidget):

def init(self, parent_vkb):

def init_ui(self):

def update_theme(self, tc):

def mousePressEvent(self, e):

def mouseMoveEvent(self, e):

def mouseReleaseEvent(self, e):

def showEvent(self, e):

def hideEvent(self, e):

def _on_close(self):

def _collect(self):

def do_load_pack(self):

def toggle_perf(self, c):

def refresh_table(self):

def _ins(self, key, file, enabled):

def _del(self, w):

def _on_cell_dbl(self, row, col):

def add_row(self):

def open_rule_dir(self):

def do_save(self):

===================== 主界面 =====================778-1053行

class VirtualKeyboardApp(QWidget):

def init(self):

def _track_fg(self):

"""★ 记住最后一个非自身的前台窗口"""

def init_tray(self):

def init_ui(self):

def _toggle_mod(self, mod, checked):

def _update_mod_styles(self):

def _vk_press(self, key):

def _vk_release(self, key):

def _style_btn(self, btn, active):

def _update_indicators(self):

def apply_styles(self):

def update_scale(self, sz):

def update_opacity(self, v):

def change_theme(self, idx):

def open_settings(self):

def toggle_vis(self):

def quit_app(self):

def mousePressEvent(self, e):

def mouseMoveEvent(self, e):

def mouseReleaseEvent(self, e):

def start_keyboard_hook(self):

def _cleanup_stuck(self):

def on_key_pressed(self, key):

def on_key_released(self, key):

主函数

python 复制代码
if __name__ == '__main__':
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
    app = QApplication(sys.argv)
    QApplication.setQuitOnLastWindowClosed(False)
    window = VirtualKeyboardApp()
    window.show()
    sys.exit(app.exec_())

AI的分析

我的疑惑

build.spec

后记

1.我走过了各种路的全流程,手动进行了命令行操作,用了bat命令,最后还打包成了exe进行操作。

2.卡住我的最大的坑是音效问题,原来是选中文件夹,导入进去就行了。

3.(于是我决定写一个项目,给它我自己的路径,能够输出目录树,毕竟要被自己的效率气晕嘞)

这个坑我马上填,尽量明天写完。

4.我还可以考虑出一个周杰伦音效包和原神音效包。但是这个就是纯做mp3,而不是做项目文件了。

相关推荐
小幂同学1 天前
笔记本触控板能用鼠标连点器吗?快捷键与位置问题解析
计算机外设·鼠标连点器·连点器
集芯微电科技有限公司2 天前
700V/17A高频开关低导通阻GaN HEMT驱动器适用于快充,LLC,PFC功率校正
人工智能·嵌入式硬件·深度学习·神经网络·机器学习·生成对抗网络·计算机外设
科技每日热闻3 天前
爱攻AGON霸天Max QD-OLED曲面电竞显示器AGP497UCZD重磅上市
科技·计算机外设
CoreTK_EMC3 天前
显示器 EMC 整改:干扰溯源、多接口处理与量产工程实践
计算机外设·芯通康·显示器 emc 整改·lvds edp emc·显示器 re 辐射超标·hdmi 接口 esd·显示器花屏闪屏
云上工程笔记3 天前
4K 显示器只能跑 30Hz 怎么办:从刷新率、HDMI 接口到线材的排查方法
计算机外设
zhonyu鱼3 天前
Escrcpy:用电脑键盘鼠标操作安卓手机的跨平台投屏工具
android·计算机外设·电脑
荣合技术服务3 天前
安装Windows Server 2008系统时 USB 鼠标键盘无法操作的解决方案
服务器·计算机外设·windows2008
呉師傅5 天前
关于惠普LaserJet1018打印机在Windows11上打印颜色偏淡的问题解决方法
运维·服务器·windows·计算机外设·电脑
DevHub5 天前
STM32 USB HID 教程:TinyUSB 实现键盘设备,从描述符到枚举
arm开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
黑科技在线5 天前
电脑开机黑屏怎么办?显示器没反应、进不了系统解决方法
计算机外设·电脑