-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript_keyboard_macro.py
More file actions
175 lines (134 loc) · 5.63 KB
/
Copy pathscript_keyboard_macro.py
File metadata and controls
175 lines (134 loc) · 5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
"""
마우스로 조작하는 키보드 매크로 녹화 / 재생 프로그램 (Windows용)
사용법:
[녹화 시작] 버튼 클릭 -> 그 순간부터 키보드 입력을 기록합니다 ("A 시점")
[녹화 정지] 버튼 클릭 -> 기록을 멈춥니다
[재생] 버튼 클릭 -> 5초 뒤에 기록한 내용을 그대로 입력합니다
(5초 동안 원하는 창을 클릭해서 포커스를 옮기세요)
[강제 종료] 버튼 클릭 -> 녹화/재생 중이어도 프로그램을 즉시 끕니다
전부 마우스 클릭으로만 조작해서, 키보드 단축키가 브라우저나 다른
프로그램이랑 겹치는 문제가 없습니다.
설치 방법 (명령 프롬프트에서):
pip install keyboard
실행 방법:
이 파일(.pyw)을 더블클릭하면 콘솔창 없이 바로 실행됩니다.
주의: 관리자 권한으로 실행해야 정상 작동할 수 있습니다.
"""
import tkinter as tk
from tkinter import messagebox
import keyboard
import time
import threading
import os
# ----------------------------------------------------------------
# 설정값 (필요하면 숫자를 바꾸세요)
# ----------------------------------------------------------------
SPEED_MULTIPLIER = 1.0 # 1.0이면 원래 속도, 숫자를 키우면 더 천천히 재생
KEY_DELAY = 0.01 # 키 하나하나 사이의 추가 대기시간(초). 씹히면 늘리기
START_DELAY = 5 # 재생 버튼 누른 뒤 몇 초 기다릴지
# ----------------------------------------------------------------
# 상태값
# ----------------------------------------------------------------
recorded_events = []
recording = False
record_start_time = None
pressed_keys = set()
is_playing = False
def on_event(event):
"""키보드 입력을 감시하다가, 녹화 중일 때만 기록합니다."""
global record_start_time
if not recording:
return
if event.event_type == "down":
if event.name in pressed_keys:
return # 키를 오래 누르고 있을 때 생기는 반복 신호는 무시
pressed_keys.add(event.name)
else: # "up"
pressed_keys.discard(event.name)
elapsed = time.time() - record_start_time
recorded_events.append((elapsed, event.name, event.event_type))
keyboard.hook(on_event)
def set_buttons_state(state):
"""녹화/재생 중일 때 버튼을 잠그거나 풀어줍니다."""
btn_start["state"] = state
btn_stop["state"] = state
btn_play["state"] = state
def start_recording():
global recording, recorded_events, record_start_time
recorded_events = []
pressed_keys.clear()
recording = True
record_start_time = time.time()
status_label.config(text="🔴 녹화 중...")
def stop_recording():
global recording
recording = False
status_label.config(text=f"⏸ 대기 중 (저장된 입력: {len(recorded_events)}개)")
def play_recording():
if not recorded_events:
messagebox.showinfo("알림", "저장된 내용이 없어요. 먼저 녹화하세요.")
return
if recording:
messagebox.showinfo("알림", "녹화 중에는 재생할 수 없어요. 먼저 정지하세요.")
return
threading.Thread(target=_play_with_delay, daemon=True).start()
def _play_with_delay():
global is_playing
is_playing = True
set_buttons_state("disabled")
for i in range(START_DELAY, 0, -1):
status_label.config(text=f"▶ {i}초 뒤에 재생 시작... (창을 클릭하세요)")
time.sleep(1)
status_label.config(text="▶ 재생 중...")
start = time.time()
for elapsed, name, event_type in recorded_events:
target_time = elapsed * SPEED_MULTIPLIER
while time.time() - start < target_time:
time.sleep(0.001)
try:
if event_type == "down":
keyboard.press(name)
else:
keyboard.release(name)
except Exception:
pass
time.sleep(KEY_DELAY)
status_label.config(text=f"⏸ 대기 중 (저장된 입력: {len(recorded_events)}개)")
set_buttons_state("normal")
is_playing = False
def reset_state():
"""프로그램을 끄지 않고, 녹화/재생 상태만 강제로 대기 상태로 되돌립니다."""
global recording, is_playing
recording = False
is_playing = False
pressed_keys.clear()
set_buttons_state("normal")
status_label.config(text=f"⏸ 대기 중 (저장된 입력: {len(recorded_events)}개)")
def force_quit():
os._exit(0) # 녹화/재생 중이어도 그 자리에서 바로 프로그램을 꺼버림
# ----------------------------------------------------------------
# GUI 구성
# ----------------------------------------------------------------
root = tk.Tk()
root.title("키보드 매크로")
root.geometry("300x330")
root.attributes("-topmost", True) # 항상 다른 창 위에 보이게
status_label = tk.Label(root, text="⏸ 대기 중", font=("Arial", 11))
status_label.pack(pady=12)
btn_start = tk.Button(root, text="① 녹화 시작", width=20, height=2, command=start_recording)
btn_start.pack(pady=4)
btn_stop = tk.Button(root, text="② 녹화 정지", width=20, height=2, command=stop_recording)
btn_stop.pack(pady=4)
btn_play = tk.Button(root, text="③ 재생 (5초 뒤 시작)", width=20, height=2, command=play_recording)
btn_play.pack(pady=4)
btn_reset = tk.Button(
root, text="④ 상태 초기화", width=20, height=2,
bg="#f0ad4e", fg="white", command=reset_state
)
btn_reset.pack(pady=4)
btn_quit = tk.Button(
root, text="🛑 강제 종료", width=20, height=2,
bg="#d9534f", fg="white", command=force_quit
)
btn_quit.pack(pady=12)
root.mainloop()