screen-keyboard 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- screen_keyboard-1.0.1/LICENSE +21 -0
- screen_keyboard-1.0.1/MANIFEST.in +7 -0
- screen_keyboard-1.0.1/PKG-INFO +122 -0
- screen_keyboard-1.0.1/README.md +92 -0
- screen_keyboard-1.0.1/pyproject.toml +50 -0
- screen_keyboard-1.0.1/requirements.txt +6 -0
- screen_keyboard-1.0.1/setup.cfg +4 -0
- screen_keyboard-1.0.1/src/screen_keyboard/app.py +246 -0
- screen_keyboard-1.0.1/src/screen_keyboard/index.html +1270 -0
- screen_keyboard-1.0.1/src/screen_keyboard.egg-info/PKG-INFO +122 -0
- screen_keyboard-1.0.1/src/screen_keyboard.egg-info/SOURCES.txt +13 -0
- screen_keyboard-1.0.1/src/screen_keyboard.egg-info/dependency_links.txt +1 -0
- screen_keyboard-1.0.1/src/screen_keyboard.egg-info/entry_points.txt +2 -0
- screen_keyboard-1.0.1/src/screen_keyboard.egg-info/requires.txt +11 -0
- screen_keyboard-1.0.1/src/screen_keyboard.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: screen-keyboard
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: 手机键盘控制电脑 - 通过手机浏览器控制电脑输入
|
|
5
|
+
Author-email: Your Name <your-email@example.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/your-username/screen-keyboard
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: flask>=2.3.0
|
|
20
|
+
Requires-Dist: flask-socketio>=5.3.0
|
|
21
|
+
Requires-Dist: pynput>=1.7.6
|
|
22
|
+
Requires-Dist: python-socketio>=5.10.0
|
|
23
|
+
Requires-Dist: python-engineio>=4.8.0
|
|
24
|
+
Requires-Dist: simple-websocket>=1.0.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest; extra == "dev"
|
|
27
|
+
Requires-Dist: black; extra == "dev"
|
|
28
|
+
Requires-Dist: flake8; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# 手机键盘控制电脑
|
|
32
|
+
|
|
33
|
+
通过手机浏览器访问网页,使用虚拟键盘控制电脑输入。
|
|
34
|
+
|
|
35
|
+
**原理**:网页发送键盘按键到电脑,由电脑上的输入法(如搜狗、微软拼音)处理拼音转换。
|
|
36
|
+
|
|
37
|
+
## 快速安装
|
|
38
|
+
|
|
39
|
+
### 方法一:pip 安装(推荐)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 安装
|
|
43
|
+
pip install screen-keyboard
|
|
44
|
+
|
|
45
|
+
# 运行
|
|
46
|
+
screen-keyboard
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 方法二:源码安装
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# 克隆或直接下载后
|
|
53
|
+
pip install -e .
|
|
54
|
+
|
|
55
|
+
# 运行
|
|
56
|
+
screen-keyboard
|
|
57
|
+
# 或
|
|
58
|
+
python app.py
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 方法三:一行命令安装
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
curl -sL https://raw.githubusercontent.com/your-username/screen-keyboard/main/install-one-line.sh | bash
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 使用方法
|
|
68
|
+
|
|
69
|
+
### 1. 启动服务
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
screen-keyboard
|
|
73
|
+
# 或
|
|
74
|
+
python app.py
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. 手机访问
|
|
78
|
+
|
|
79
|
+
服务端启动后会显示局域网地址,例如:
|
|
80
|
+
```
|
|
81
|
+
局域网地址:http://192.168.1.100:5000
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
在手机上连接同一 WiFi,用浏览器访问该地址即可。
|
|
85
|
+
|
|
86
|
+
## 功能
|
|
87
|
+
|
|
88
|
+
- ✅ 全键盘布局(QWERTY)
|
|
89
|
+
- ✅ 符号/数字键盘切换
|
|
90
|
+
- ✅ Shift 大写切换
|
|
91
|
+
- ✅ 特殊按键(回车、退格、空格)
|
|
92
|
+
- ✅ 方向键(倒 T 布局)
|
|
93
|
+
- ✅ 触控板鼠标控制
|
|
94
|
+
- ✅ 摇杆鼠标控制
|
|
95
|
+
- ✅ 鼠标左右中键 + 滚轮
|
|
96
|
+
- ✅ Win+Space 中英文切换
|
|
97
|
+
- ✅ 拖动窗口/文件(双击触控板后拖动)
|
|
98
|
+
|
|
99
|
+
## 说明
|
|
100
|
+
|
|
101
|
+
- 确保手机和电脑在同一局域网
|
|
102
|
+
- 电脑需开启拼音输入法
|
|
103
|
+
- 如果防火墙阻止,请开放 5000 端口
|
|
104
|
+
|
|
105
|
+
## 开发
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# 创建 conda 环境
|
|
109
|
+
conda env create -f environment.yml
|
|
110
|
+
conda activate screen-keyboard
|
|
111
|
+
|
|
112
|
+
# 安装依赖
|
|
113
|
+
pip install -r requirements.txt
|
|
114
|
+
|
|
115
|
+
# 运行
|
|
116
|
+
python app.py
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT License
|
|
122
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# 手机键盘控制电脑
|
|
2
|
+
|
|
3
|
+
通过手机浏览器访问网页,使用虚拟键盘控制电脑输入。
|
|
4
|
+
|
|
5
|
+
**原理**:网页发送键盘按键到电脑,由电脑上的输入法(如搜狗、微软拼音)处理拼音转换。
|
|
6
|
+
|
|
7
|
+
## 快速安装
|
|
8
|
+
|
|
9
|
+
### 方法一:pip 安装(推荐)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 安装
|
|
13
|
+
pip install screen-keyboard
|
|
14
|
+
|
|
15
|
+
# 运行
|
|
16
|
+
screen-keyboard
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 方法二:源码安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# 克隆或直接下载后
|
|
23
|
+
pip install -e .
|
|
24
|
+
|
|
25
|
+
# 运行
|
|
26
|
+
screen-keyboard
|
|
27
|
+
# 或
|
|
28
|
+
python app.py
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 方法三:一行命令安装
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
curl -sL https://raw.githubusercontent.com/your-username/screen-keyboard/main/install-one-line.sh | bash
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 使用方法
|
|
38
|
+
|
|
39
|
+
### 1. 启动服务
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
screen-keyboard
|
|
43
|
+
# 或
|
|
44
|
+
python app.py
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. 手机访问
|
|
48
|
+
|
|
49
|
+
服务端启动后会显示局域网地址,例如:
|
|
50
|
+
```
|
|
51
|
+
局域网地址:http://192.168.1.100:5000
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
在手机上连接同一 WiFi,用浏览器访问该地址即可。
|
|
55
|
+
|
|
56
|
+
## 功能
|
|
57
|
+
|
|
58
|
+
- ✅ 全键盘布局(QWERTY)
|
|
59
|
+
- ✅ 符号/数字键盘切换
|
|
60
|
+
- ✅ Shift 大写切换
|
|
61
|
+
- ✅ 特殊按键(回车、退格、空格)
|
|
62
|
+
- ✅ 方向键(倒 T 布局)
|
|
63
|
+
- ✅ 触控板鼠标控制
|
|
64
|
+
- ✅ 摇杆鼠标控制
|
|
65
|
+
- ✅ 鼠标左右中键 + 滚轮
|
|
66
|
+
- ✅ Win+Space 中英文切换
|
|
67
|
+
- ✅ 拖动窗口/文件(双击触控板后拖动)
|
|
68
|
+
|
|
69
|
+
## 说明
|
|
70
|
+
|
|
71
|
+
- 确保手机和电脑在同一局域网
|
|
72
|
+
- 电脑需开启拼音输入法
|
|
73
|
+
- 如果防火墙阻止,请开放 5000 端口
|
|
74
|
+
|
|
75
|
+
## 开发
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 创建 conda 环境
|
|
79
|
+
conda env create -f environment.yml
|
|
80
|
+
conda activate screen-keyboard
|
|
81
|
+
|
|
82
|
+
# 安装依赖
|
|
83
|
+
pip install -r requirements.txt
|
|
84
|
+
|
|
85
|
+
# 运行
|
|
86
|
+
python app.py
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
MIT License
|
|
92
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "screen-keyboard"
|
|
7
|
+
version = "1.0.1"
|
|
8
|
+
description = "手机键盘控制电脑 - 通过手机浏览器控制电脑输入"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [{name = "Your Name", email = "your-email@example.com"}]
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.8",
|
|
18
|
+
"Programming Language :: Python :: 3.9",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"flask>=2.3.0",
|
|
25
|
+
"flask-socketio>=5.3.0",
|
|
26
|
+
"pynput>=1.7.6",
|
|
27
|
+
"python-socketio>=5.10.0",
|
|
28
|
+
"python-engineio>=4.8.0",
|
|
29
|
+
"simple-websocket>=1.0.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
dev = ["pytest", "black", "flake8"]
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
screen-keyboard = "screen_keyboard.app:main"
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/your-username/screen-keyboard"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools]
|
|
42
|
+
package-dir = {"" = "src"}
|
|
43
|
+
include-package-data = true
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.packages.find]
|
|
46
|
+
where = ["src"]
|
|
47
|
+
include = ["*"]
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.package-data]
|
|
50
|
+
"*" = ["*.html", "*.md", "*.txt"]
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
手机键盘控制电脑 - 服务端
|
|
4
|
+
使用 Flask + Socket.IO 实现 WebSocket 通信
|
|
5
|
+
使用 pynput 模拟键盘输入
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import socket
|
|
10
|
+
from flask import Flask, send_from_directory, request
|
|
11
|
+
from flask_socketio import SocketIO
|
|
12
|
+
from pynput.keyboard import Controller, Key, KeyCode
|
|
13
|
+
from pynput.mouse import Controller as MouseController, Button
|
|
14
|
+
|
|
15
|
+
# 获取包所在目录
|
|
16
|
+
PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
17
|
+
|
|
18
|
+
app = Flask(__name__, static_folder=PACKAGE_DIR)
|
|
19
|
+
app.config['SECRET_KEY'] = 'secret!'
|
|
20
|
+
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading', transports=['polling', 'websocket'])
|
|
21
|
+
|
|
22
|
+
keyboard = Controller()
|
|
23
|
+
mouse = MouseController()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_local_ip():
|
|
27
|
+
"""获取本机局域网 IP 地址"""
|
|
28
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
29
|
+
try:
|
|
30
|
+
s.connect(('10.255.255.255', 1))
|
|
31
|
+
ip = s.getsockname()[0]
|
|
32
|
+
except:
|
|
33
|
+
ip = '127.0.0.1'
|
|
34
|
+
finally:
|
|
35
|
+
s.close()
|
|
36
|
+
return ip
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@app.route('/')
|
|
40
|
+
def index():
|
|
41
|
+
return send_from_directory(PACKAGE_DIR, 'index.html')
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@socketio.on('connect')
|
|
45
|
+
def handle_connect():
|
|
46
|
+
print(f'客户端连接:{request.sid}')
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@socketio.on('disconnect')
|
|
50
|
+
def handle_disconnect():
|
|
51
|
+
print(f'客户端断开:{request.sid}')
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@socketio.on('key')
|
|
55
|
+
def handle_key(data):
|
|
56
|
+
"""处理键盘按键事件"""
|
|
57
|
+
key = data.get('key', '')
|
|
58
|
+
key_type = data.get('type', 'char')
|
|
59
|
+
|
|
60
|
+
if key_type == 'special':
|
|
61
|
+
if not handle_special_key(key):
|
|
62
|
+
print(f'Unknown special key: {key}')
|
|
63
|
+
else:
|
|
64
|
+
keyboard.type(key)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@socketio.on('key_combo')
|
|
68
|
+
def handle_key_combo(data):
|
|
69
|
+
"""处理组合键 (如 Ctrl+Tab、Ctrl+C、Win+Space、Ctrl+Shift+C)"""
|
|
70
|
+
key = data.get('key', '')
|
|
71
|
+
ctrl = data.get('ctrl', False)
|
|
72
|
+
ctrl_right = data.get('ctrl_right', False)
|
|
73
|
+
alt = data.get('alt', False)
|
|
74
|
+
alt_right = data.get('alt_right', False)
|
|
75
|
+
win = data.get('win', False)
|
|
76
|
+
shift = data.get('shift', False)
|
|
77
|
+
shift_right = data.get('shift_right', False)
|
|
78
|
+
|
|
79
|
+
# 构建修饰键列表
|
|
80
|
+
modifiers = []
|
|
81
|
+
if ctrl:
|
|
82
|
+
modifiers.append(Key.ctrl)
|
|
83
|
+
if ctrl_right:
|
|
84
|
+
modifiers.append(Key.ctrl_r)
|
|
85
|
+
if alt:
|
|
86
|
+
modifiers.append(Key.alt)
|
|
87
|
+
if alt_right:
|
|
88
|
+
modifiers.append(Key.alt_r)
|
|
89
|
+
if win:
|
|
90
|
+
modifiers.append(Key.cmd)
|
|
91
|
+
if shift:
|
|
92
|
+
modifiers.append(Key.shift)
|
|
93
|
+
if shift_right:
|
|
94
|
+
modifiers.append(Key.shift_r)
|
|
95
|
+
|
|
96
|
+
# 按顺序按下修饰键
|
|
97
|
+
for mod in modifiers:
|
|
98
|
+
keyboard.press(mod)
|
|
99
|
+
|
|
100
|
+
# 按下目标键
|
|
101
|
+
if len(key) == 1:
|
|
102
|
+
keyboard.press(key.lower())
|
|
103
|
+
keyboard.release(key.lower())
|
|
104
|
+
else:
|
|
105
|
+
# 特殊键
|
|
106
|
+
handle_special_key(key)
|
|
107
|
+
|
|
108
|
+
# 释放修饰键
|
|
109
|
+
for mod in reversed(modifiers):
|
|
110
|
+
keyboard.release(mod)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# ===== 鼠标控制 =====
|
|
114
|
+
@socketio.on('mouse_move')
|
|
115
|
+
def handle_mouse_move(data):
|
|
116
|
+
"""处理鼠标移动"""
|
|
117
|
+
x = data.get('x', 0)
|
|
118
|
+
y = data.get('y', 0)
|
|
119
|
+
mouse.move(x, y)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@socketio.on('mouse_click')
|
|
123
|
+
def handle_mouse_click(data):
|
|
124
|
+
"""处理鼠标点击"""
|
|
125
|
+
button = data.get('button', 'left')
|
|
126
|
+
if button == 'left':
|
|
127
|
+
mouse.click(Button.left)
|
|
128
|
+
elif button == 'right':
|
|
129
|
+
mouse.click(Button.right)
|
|
130
|
+
elif button == 'middle':
|
|
131
|
+
mouse.click(Button.middle)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@socketio.on('mouse_press')
|
|
135
|
+
def handle_mouse_press(data):
|
|
136
|
+
"""处理鼠标按键按下/释放(用于拖动)"""
|
|
137
|
+
button = data.get('button', 'left')
|
|
138
|
+
pressed = data.get('pressed', True)
|
|
139
|
+
if button == 'left':
|
|
140
|
+
if pressed:
|
|
141
|
+
mouse.press(Button.left)
|
|
142
|
+
else:
|
|
143
|
+
mouse.release(Button.left)
|
|
144
|
+
elif button == 'right':
|
|
145
|
+
if pressed:
|
|
146
|
+
mouse.press(Button.right)
|
|
147
|
+
else:
|
|
148
|
+
mouse.release(Button.right)
|
|
149
|
+
elif button == 'middle':
|
|
150
|
+
if pressed:
|
|
151
|
+
mouse.press(Button.middle)
|
|
152
|
+
else:
|
|
153
|
+
mouse.release(Button.middle)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@socketio.on('mouse_scroll')
|
|
157
|
+
def handle_mouse_scroll(data):
|
|
158
|
+
"""处理鼠标滚轮"""
|
|
159
|
+
direction = data.get('direction', 'up')
|
|
160
|
+
if direction == 'up':
|
|
161
|
+
mouse.scroll(0, 3)
|
|
162
|
+
else:
|
|
163
|
+
mouse.scroll(0, -3)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def handle_special_key(key):
|
|
167
|
+
"""处理特殊按键"""
|
|
168
|
+
key_map = {
|
|
169
|
+
# 基础控制键
|
|
170
|
+
'Enter': Key.enter,
|
|
171
|
+
'Backspace': Key.backspace,
|
|
172
|
+
'Space': Key.space,
|
|
173
|
+
'Tab': Key.tab,
|
|
174
|
+
'Escape': Key.esc,
|
|
175
|
+
'CapsLock': Key.caps_lock,
|
|
176
|
+
|
|
177
|
+
# 修饰键
|
|
178
|
+
'Ctrl': Key.ctrl,
|
|
179
|
+
'CtrlRight': Key.ctrl_r,
|
|
180
|
+
'Alt': Key.alt,
|
|
181
|
+
'AltRight': Key.alt_r,
|
|
182
|
+
'Shift': Key.shift,
|
|
183
|
+
'ShiftRight': Key.shift_r,
|
|
184
|
+
'Super': Key.cmd,
|
|
185
|
+
'SuperRight': Key.cmd_r,
|
|
186
|
+
'Menu': Key.menu,
|
|
187
|
+
|
|
188
|
+
# 方向键
|
|
189
|
+
'ArrowUp': Key.up,
|
|
190
|
+
'ArrowDown': Key.down,
|
|
191
|
+
'ArrowLeft': Key.left,
|
|
192
|
+
'ArrowRight': Key.right,
|
|
193
|
+
|
|
194
|
+
# 导航键
|
|
195
|
+
'Insert': Key.insert,
|
|
196
|
+
'Delete': Key.delete,
|
|
197
|
+
'Home': Key.home,
|
|
198
|
+
'End': Key.end,
|
|
199
|
+
'PageUp': Key.page_up,
|
|
200
|
+
'PageDown': Key.page_down,
|
|
201
|
+
|
|
202
|
+
# 功能键
|
|
203
|
+
'F1': Key.f1,
|
|
204
|
+
'F2': Key.f2,
|
|
205
|
+
'F3': Key.f3,
|
|
206
|
+
'F4': Key.f4,
|
|
207
|
+
'F5': Key.f5,
|
|
208
|
+
'F6': Key.f6,
|
|
209
|
+
'F7': Key.f7,
|
|
210
|
+
'F8': Key.f8,
|
|
211
|
+
'F9': Key.f9,
|
|
212
|
+
'F10': Key.f10,
|
|
213
|
+
'F11': Key.f11,
|
|
214
|
+
'F12': Key.f12,
|
|
215
|
+
|
|
216
|
+
# 其他
|
|
217
|
+
'PrintScreen': Key.print_screen,
|
|
218
|
+
'ScrollLock': Key.scroll_lock,
|
|
219
|
+
'Pause': Key.pause,
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if key in key_map:
|
|
223
|
+
keyboard.press(key_map[key])
|
|
224
|
+
keyboard.release(key_map[key])
|
|
225
|
+
return True
|
|
226
|
+
return False
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def main():
|
|
230
|
+
"""命令行入口"""
|
|
231
|
+
local_ip = get_local_ip()
|
|
232
|
+
port = 5000
|
|
233
|
+
|
|
234
|
+
print("=" * 50)
|
|
235
|
+
print("手机键盘控制电脑 - 服务端已启动")
|
|
236
|
+
print("=" * 50)
|
|
237
|
+
print(f"局域网地址:http://{local_ip}:{port}")
|
|
238
|
+
print(f"\n请在手机浏览器访问上述地址")
|
|
239
|
+
print("按 Ctrl+C 停止服务")
|
|
240
|
+
print("=" * 50)
|
|
241
|
+
|
|
242
|
+
socketio.run(app, host='0.0.0.0', port=port, debug=False, allow_unsafe_werkzeug=True)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
if __name__ == '__main__':
|
|
246
|
+
main()
|