QtScrcpy 按键映射完全指南5 种映射类型逐字段拆解3 步配好你自己的 KeyMap 脚本【免费下载链接】QtScrcpyAndroid real-time display control software项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpyQtScrcpy 是一款 Android 实时投屏控制软件它的自定义按键映射KeyMap功能可以更进一步用一份 JSON 脚本把键盘、鼠标按键和鼠标移动映射成手机上指定位置的点击、拖拽乃至 FPS 游戏的虚拟方向盘。读完本文你可以读懂仓库自带的全部示例脚本独立编写新的游戏按键映射并完成点位校准、灵敏度调试与下发应用。如需获取完整仓库含 keymap 目录下的官方示例git clone https://gitcode.com/GitHub_Trending/qt/QtScrcpy映射文件如何流转从 keymap 目录到设备很多读者以为把 JSON 丢进仓库的 keymap 目录就万事大吉但源码里的加载机制其实分两层理解它才能解释为什么我新建的文件刷不出来。getKeyMapPath()QtScrcpy/ui/dialog.cpp L61-L73负责解析用户映射目录优先取环境变量QTSCRCPY_KEYMAP_PATH未设置则回退到 Qt 的 AppData 位置下的keymap子目录并用mkpath自动创建。getDefaultKeyMapPath()同文件 L75-L84解析默认映射目录优先取环境变量QTSCRCPY_DEFAULT_KEYMAP_PATH未设置则为可执行文件所在目录的keymap/子目录——仓库里那 5 个官方示例就属于这一层。两者的协作逻辑是initializeKeyMapDirectory()L86-L101在启动时把默认目录中用户目录里还没有的*.json复制过去on_refreshGameScriptBtn_clicked()L1366-L1387刷新下拉框时按*.json通配符同时扫描两个目录不含子目录与符号链接同名文件用户目录优先去重两个目录都不存在时控制台输出keymap directory not find。应用流程在on_applyScriptBtn_clicked()L1389-L1398读取选中文件后调用device-updateScript(...)把 JSON 原文下发到设备解析与模拟触摸的执行逻辑在核心库 QtScrcpyCore 中完成。也就是说主界面刷新游戏脚本 → 下拉框选择 → 应用脚本这三步就是脚本进入手机的完整通路。一个容易忽略的点主界面高级配置里还有一个按钮会直接openUserDirectory(getKeyMapPath())dialog.cpp L514-L516打开用户映射目录建议把自定义文件放在这里升级程序时默认目录被重新同步也不会覆盖你的改动。全脚本通用的两条约定相对坐标与 Qt 按键码所有坐标都是归一化的相对坐标屏幕宽和高都用 1 表示。以 1920x1080 屏幕为例坐标(0.5, 0.5)对应像素位置(1920, 1080) × (0.5, 0.5) (960, 540)原点在屏幕左上角。这样同一份映射可以通吃不同分辨率的设备。所有按键码使用 Qt 的键名枚举如Key_A、Key_Space、Key_Tab、Key_QuoteLeft鼠标则是LeftButton/RightButton。完整取值可查阅 Qt 官方文档的 The key names used by Qt. 一节。拿坐标有现成捷径连接设备后用鼠标左键单击投屏画面控制台会直接打印该点归一化后的pos可直接复制进 JSON。这段调试逻辑在 QtScrcpy/ui/videoform.cpp L787-L793// debug keymap pos if (event-button() Qt::LeftButton) { qreal x localPos.x() / vw-size().width(); qreal y localPos.y() / vw-size().height(); QString posTip QString(R(pos: {x: %1, y: %2})).arg(x).arg(y); qInfo() posTip.toStdString().c_str(); }它证明了输出的正是点击位置 ÷ 视频控件尺寸的归一化值和你写进映射的格式完全一致无需心算换算。另外建议在安卓开发者选项中打开触摸点观察开关可以直观看到模拟触摸落点便于对照校准。顶层结构switchKey、mouseMoveMap、keyMapNodes一份映射文件只有三个顶层字段全部可选缺省则对应功能不启用{ switchKey: Key_QuoteLeft, mouseMoveMap: { startPos: {x: 0.57, y: 0.26}, speedRatioX: 3.25, speedRatioY: 1.25 }, keyMapNodes: [] }字段作用switchKey自定义映射的开关键。默认是普通映射鼠标直控按下它在普通/自定义映射间切换。取值不限于字母键identityv.json 就用RightButton作开关键mouseMoveMap鼠标移动映射对象把鼠标位移变成手指拖动详见下一节keyMapNodes按键映射数组每个元素都必须用type字段声明五种类型之一五种映射类型逐字段拆解KMT_CLICK普通点击按键按下 → 模拟手指按下按键抬起 → 模拟手指抬起是出现频率最高的类型。字段说明key要映射的按键码pos模拟触摸的位置相对坐标switchMap是否释放鼠标。为true时除模拟触摸外还会把鼠标操作交还给界面——地图、背包这类需要鼠标点选的点位必须设true{ comment: 跳, type: KMT_CLICK, key: Key_Space, pos: {x: 0.96, y: 0.7}, switchMap: false }KMT_CLICK_TWICE两次点击按键按下时模拟一次按下再抬起按键抬起时再模拟一次等于一键双击。和平精英里的左右探头Q/E 键就是靠它实现的{ comment: 左探头, type: KMT_CLICK_TWICE, key: Key_Q, pos: {x: 0.12, y: 0.35} }KMT_CLICK_MULTI一键多点按下一次按键按clickNodes数组里的delay毫秒与pos依次点击多个位置适合一键完成一串顺序操作的场景。keymap/test.json 给出完整示例——按一次空格先延迟 500ms 点(0.5, 0.5)再延迟 500ms 点(0.8, 0.8){ comment: 测试一键多点, type: KMT_CLICK_MULTI, key: Key_Space, clickNodes: [ {delay: 500, pos: {x: 0.5, y: 0.5}}, {delay: 500, pos: {x: 0.8, y: 0.8}} ] }KMT_DRAG拖拽按键按下 → 手指在startPos按下并拖动到endPos按键抬起 → 手指抬起。字段默认值取值范围作用key——触发拖拽的按键码startPos/endPos—相对坐标拖动起点与终点dragSpeed1.00-1拖动速度越大越快startDelay可选毫秒开始拖动前等待的时间{ comment: 测试拖拽, type: KMT_DRAG, key: Key_Up, startPos: {x: 0.5, y: 0.7}, endPos: {x: 0.5, y: 0.3} }KMT_STEER_WHEEL方向盘专用于 FPS 手游的虚拟摇杆需要 4 个按键配合。按下方向键时模拟从centerPos向对应方向拖出相应 offset松开即回中{ comment: 方向盘, type: KMT_STEER_WHEEL, centerPos: {x: 0.16, y: 0.75}, leftKey: Key_A, rightKey: Key_D, upKey: Key_W, downKey: Key_S, leftOffset: 0.1, rightOffset: 0.1, upOffset: 0.27, downOffset: 0.2 }字段作用centerPos方向盘中心点leftKey/rightKey/upKey/downKey四个方向的触发按键leftOffset/rightOffset按左/右键后相对中心水平偏左/右的距离upOffset/downOffset按上/下键后相对中心垂直偏上/下的距离mouseMoveMap鼠标移动如何变成手指拖动灵敏度下限是多少mouseMoveMap开启后鼠标移动被映射为以startPos为起点、以鼠标移动方向为拖动方向的手指拖动期间鼠标会被隐藏且移动范围受限一般用于 FPS 手游转视角。字段默认值取值约束作用startPos—相对坐标手指拖动的起始点speedRatio—必须大于 0.00225鼠标到手指的整体比例越大灵敏度越低Y 轴以 2.25 的比率平移speedRatioX—至少0.001X 轴单独灵敏度屏幕比例不合适用它微调speedRatioY—至少0.001Y 轴单独灵敏度smallEyes—内嵌KMT_CLICK节点小眼睛按键按下后鼠标移动改以smallEyes.pos为起点拖动用于瞄周围gameforpeace.json 的写法很典型startPos取(0.57, 0.26)speedRatioX: 3.25、speedRatioY: 1.25分别适配横屏比例speedRatio: 10作整体基准smallEyes节点绑定Key_Alt、落点(0.8, 0.31)。实战走查解剖和平精英映射文件 keymap/gameforpeace.json 是一份可直接套用的 FPS 模板按段落看它解决了什么问题顶层与视野段L2-L21switchKey用Key_QuoteLeft键盘左上角~键切换普通/自定义映射mouseMoveMap负责转视角Alt 键触发小眼睛。方向盘段L23-L38KMT_STEER_WHEEL中心(0.16, 0.75)正落在屏幕左下摇杆区W/A/S/D 对应上下左右注意upOffset取 0.27、其余方向 0.1~0.2是为了匹配游戏摇杆纵向行程比横向长的实际手感。按键点位段L39-L32620 余个节点几乎覆盖全部高频操作——Q/E 探头CLICK_TWICE、空格跳跃、M 地图与 Tab 背包switchMap: true释放鼠标便于点选、Z 趴、C 蹲、R 换弹、F/G/H 三连拾取、1/2 切枪、Shift 车加速、F1~F4 菜单类均switchMap: true、X 开关门、T 舔包并把LeftButton映射为开枪、RightButton映射为开镜。编写自己的映射时直接以该文件为模板只替换key与pos即可keymap/tiktok.json 则演示了另一极端4 个方向键全用KMT_DRAG实现滑动翻页连mouseMoveMap都不需要。FRAG.json 里的中心点坐标精确到(0.194792, 0.716484)说明坐标就是普通浮点数点击画面拿到的长小数可以直接用。可视化按键映射工具不想手写 JSON 的话有两个途径QuickAssistant 可直接在图上摆放按键点位仓库截图展示了这类工具配置游戏映射的典型界面另一个是 Web 端 GUI 工具 ScrcpyKeyMapper支持直观创建映射、实时测试、导出为 JSON、导入现有映射编辑并附在线试用版。用它们布好点位后导出 JSON丢进 keymap 目录即可被 QtScrcpy 识别。坐标采集与排错清单 ⚠️按出现频率排序的排错路径全部可在操作层面定位新文件刷不出来先确认文件名是.json刷新逻辑只匹配该通配符再确认放进了用户映射目录QTSCRCPY_KEYMAP_PATH或 AppData 下keymap/。控制台出现keymap directory not find说明两个目录都不存在需先创建。控制台报open file failed: xxx来自getGameScript()dialog.cpp L727-L745表示用户与默认目录都没找到该文件检查文件名与下拉框显示是否一致。触摸落点有偏差别手算坐标用左键单击画面让控制台打印pos同时在开发者选项打开触摸观察开关对照手机侧真实触点。转视角过快/过飘检查speedRatioX/Y是否低于 0.001 下限数值越大灵敏度越低逐步上调。菜单类点位选不中地图、背包、菜单打开后必须鼠标点选对应节点switchMap设为true。映射完全无响应核对type五种取值是否拼写正确、key是否为合法 Qt 键名以及是否按了switchKey切进自定义映射模式。上线前约束速查文件放 keymap 目录用户目录或默认目录必须是*.json刷新后出现在下拉框坐标一律 0~1 相对值左键单击画面可直接复制现成postype只能是KMT_CLICK/KMT_CLICK_TWICE/KMT_CLICK_MULTI/KMT_DRAG/KMT_STEER_WHEEL数值边界speedRatio大于 0.00225speedRatioX/Y至少 0.001dragSpeed取 0~1默认 1.0需要鼠标接管界面的点位地图、菜单、背包把switchMap设为true常规点位保持false给每个节点加comment字段后续维护与可视化工具都靠它识别点位用途【免费下载链接】QtScrcpyAndroid real-time display control software项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考