제가 프로그램 만드는 과정을 다루다 보니 전체화면을 스크린샷 해야 하는 경우가 생겼습니다. 하지만 제 키보드는 Numless 키보드로 일명 독거미 키보드입니다. 그래서 프린트스크린샷 키가 존재하지 않습니다. 그 계기로 프로그램을 만들어보면 어떨까 하고 바로 만들어보려 합니다. 저 같은 경우의 사람들에게 유용하겠죠? 시작해 보겠습니다.
프롬프트
프린트스크린샷 기능을 일정 단축키로 지정하고 그키를 눌렀을때 프린트스크린샷 기능을 하도록 해주는 프로그램을 만들어줘 GUI로 만들고 단축키입력 제목의 단축키를 눌러서 입력할 수 있는 창이 있으면 좋겠어
ChatGPT 결과
여기 있습니다! 이 프로그램은 GUI 환경에서 단축키를 설정하고, 해당 단축키를 누르면 자동으로 스크린샷을 찍어 저장 및 오픈해주는 기능을 갖추고 있습니다. 단축키는 입력 필드에 직접 누르면서 설정할 수 있으며, 설정 후에는 해당 키를 눌러서 바로 스크린샷을 찍을 수 있습니다. 추가적인 디자인 개선이 필요하면 말씀해 주세요! 😊
코드
import tkinter as tk
from tkinter import ttk
from pynput import keyboard
import pyautogui
import time
import os
class ScreenshotApp:
def __init__(self, root):
self.root = root
self.root.title("프린트 스크린 단축키 설정")
self.root.geometry("400x200")
self.hotkey = None
ttk.Label(root, text="단축키 설정").pack(pady=10)
self.hotkey_entry = ttk.Entry(root, justify="center", font=("Arial", 12))
self.hotkey_label = ttk.Label(root, text="단축키 입력 후 엔터를 누르세요.")
self.hotkey_button = ttk.Button(root, text="단축키 입력", command=self.capture_hotkey)
self.save_button = ttk.Button(root, text="설정 저장", command=self.save_hotkey)
self.hotkey_label = ttk.Label(root, text="현재 설정: 없음")
self.hotkey_label.pack(pady=5)
self.hotkey_input = ttk.Entry(root, width=20)
self.hotkey_label.pack()
self.hotkey_button.pack(pady=10)
self.hotkey_entry = tk.StringVar()
self.hotkey_entry = ttk.Entry(root, textvariable=self.hotkey, width=20)
self.hotkey_entry = ttk.Entry(root, textvariable=tk.StringVar(), width=30)
self.hotkey_entry.bind("<KeyPress>", self.detect_key)
self.hotkey_entry.pack()
self.hotkey_label.pack()
self.set_hotkey_button.pack(pady=10)
self.root.bind_all("<KeyPress>", self.on_key_press)
def detect_key(self, event):
self.hotkey = event.keysym
self.hotkey_label.config(text=f"현재 설정: {self.hotkey}")
def save_hotkey(self):
if self.hotkey:
self.root.unbind_all(f"<{self.hotkey}>")
self.root.bind_all(f"<{self.hotkey}>", self.take_screenshot)
self.hotkey_label.config(text=f"현재 설정: {self.hotkey}")
def take_screenshot(self, event=None):
self.root.iconify()
x = root.winfo_rootx()
y = root.winfo_rooty()
w = self.root.winfo_width()
h = self.root.winfo_height()
root.after(500, self.capture, x, y, w, h)
def capture(self, x, y, w, h):
import time
time.sleep(0.5)
import pyautogui
from datetime import datetime
screenshot = pyautogui.screenshot(region=(x, y, w, h))
save_path = f"screenshot_{time.strftime('%Y%m%d%H%M%S')}.png"
screenshot_path = f"{save_dir}/{save_name}.png"
try:
screenshot = pyautogui.screenshot(region=(x, y, w, h))
screenshot.save(screenshot_path)
os.startfile(screenshot_path)
except Exception as e:
print("스크린샷 저장 오류:", e)
# 실행
root = tk.Tk()
app = ScreenshotApp(root)
root.mainloop()
에러
Traceback (most recent call last):
File "C:\Users\qwe\pythonPG\screenshotHotkey.py", line 3, in <module>
from pynput import keyboard
ModuleNotFoundError: No module named 'pynput'
오래간만에 에러를 미리 안 알려줬습니다. 에러해결을 해보겠습니다.
GPT 해결책
이 오류는 pynput 모듈이 설치되지 않았기 때문입니다.
아래 명령어를 실행하여 pynput을 설치하면 해결됩니다.
만약 실행해도 같은 에러가 발생한다면, 다음을 확인해주세요.
- 올바른 가상 환경(venv)을 활성화했는지 확인하세요.
- 예: source venv/bin/activate (Linux/macOS)
- 예: venv\\Scripts\\activate (Windows)
- 그래도 안 되면 관리자 권한으로 실행 후, 다음 명령어를 실행해보세요.
설치가 끝난 후에도 같은 오류가 발생한다면, 어떤 환경에서 실행 중인지(예: Anaconda, 가상환경 여부 등)를 알려주세요! 😊
두 번째 에러
Traceback (most recent call last):
File "C:\Users\qwe\pythonPG\screenshotHotkey.py", line 4, in <module>
import pyautogui
ModuleNotFoundError: No module named 'pyautogui'
GPT 해결책
pyautogui 모듈이 설치되지 않아서 발생하는 오류입니다.
아래 명령어를 실행하여 pyautogui를 설치하세요.
.
.
.
이하생략
세 번째 에러
Traceback (most recent call last):
File "C:\Users\qwe\pythonPG\screenshotHotkey.py", line 78, in <module>
app = ScreenshotApp(root)
File "C:\Users\qwe\pythonPG\screenshotHotkey.py", line 20, in __init__
self.hotkey_button = ttk.Button(root, text="단축키 입력", command=self.capture_hotkey)
^^^^^^^^^^^^^^^^^^^
AttributeError: 'ScreenshotApp' object has no attribute 'capture_hotkey'
이번에는 좀 쉽지 않네요. 하지만 끈기를 가지세요~ ^^
GPT 해결책
🔥 수정된 부분
- capture_hotkey 함수 삭제
- 원래 코드에 capture_hotkey 함수가 없었기 때문에 start_hotkey_capture로 수정함.
- 올바른 단축키 감지 (detect_key)
- 단축키를 입력하면 self.hotkey에 저장하도록 수정.
- 단축키 저장 (save_hotkey)
- 단축키를 설정하면 해당 키를 눌렀을 때 스크린샷을 찍도록 이벤트 바인딩.
- 스크린샷 기능 (take_screenshot)
- 설정된 단축키를 누르면 스크린샷을 찍고 자동으로 파일을 열도록 변경.
수정된 코드를 보여주는데 자동으로 소스를 수정해주진 않았습니다. 편집 버튼을 클릭하면 자동으로 소스를 수정해 줍니다.
결과
이제야 정상적으로 나옵니다. 실행을 해본 결과 단축키가 하나만 설정되고 설정저장은 잘되고 표현도 좋습니다. 그리고 캡처하면 해당창이 사라지고 전체창이 캡처되는 것을 확인했습니다.
이것으로 만족할 수도 있지만 역시 고도화를 해보겠습니다.
고도화
단축키입력이 최대 세 개를 눌러 설정가능하도록 해줘 예를 들어 ctrl + shift + s 같은 형태의 키입력으로 s + d + f 같은 형태는 안되게 설정해재 버튼도 하나 추가해 줘
ChatGPT 결과
업데이트하여 최대 3개의 조합 키(예: Ctrl + Shift + S) 를 지원하고, 설정 해제 버튼을 추가했습니다.
이제 Ctrl, Shift, Alt 등의 조합 키를 포함한 핫키를 설정할 수 있으며, 일반 키만 여러 개 입력하는 것은 방지됩니다. 🚀
업데이트된 코드를 반영합니다.
✅ 업데이트 완료!
이제 최대 3개의 조합 키 (Ctrl, Shift, Alt 포함)로 단축키 설정이 가능하며, "설정 해제" 버튼을 추가하여 설정을 초기화할 수 있습니다.
테스트해보시고 추가 수정이 필요하면 알려주세요! 🚀
원하는데로 일반 키 여러 개 입력을 방지시켜 줬네요.
소스
import tkinter as tk
from tkinter import ttk
from pynput import keyboard
import pyautogui
import time
import os
class ScreenshotApp:
def __init__(self, root):
self.root = root
self.root.title("프린트 스크린 단축키 설정")
self.root.geometry("400x250")
self.hotkeys = set()
self.listener = keyboard.Listener(on_press=self.detect_key, on_release=self.release_key)
self.listener.start()
ttk.Label(root, text="단축키 설정").pack(pady=10)
self.hotkey_label = ttk.Label(root, text="현재 설정: 없음")
self.hotkey_label.pack(pady=5)
self.hotkey_button = ttk.Button(root, text="단축키 입력", command=self.start_hotkey_capture)
self.save_button = ttk.Button(root, text="설정 저장", command=self.save_hotkey)
self.reset_button = ttk.Button(root, text="설정 해제", command=self.reset_hotkey)
self.hotkey_button.pack(pady=5)
self.save_button.pack(pady=5)
self.reset_button.pack(pady=5)
def start_hotkey_capture(self):
self.hotkeys.clear()
self.hotkey_label.config(text="단축키 입력 중... (Ctrl, Shift, Alt 조합 가능)")
def detect_key(self, key):
if hasattr(key, 'name') and key.name in ('ctrl', 'shift', 'alt'):
self.hotkeys.add(key.name)
elif hasattr(key, 'char') and key.char:
if len(self.hotkeys) > 0 and len(self.hotkeys) < 3:
self.hotkeys.add(key.char.lower())
self.update_hotkey_label()
def release_key(self, key):
pass # 키를 놓는 동작에서는 아무 작업도 하지 않음
def update_hotkey_label(self):
if self.hotkeys:
self.hotkey_label.config(text=f"현재 설정: {' + '.join(self.hotkeys)}")
else:
self.hotkey_label.config(text="현재 설정: 없음")
def save_hotkey(self):
if self.hotkeys:
self.root.bind_all("<KeyPress>", self.take_screenshot)
self.hotkey_label.config(text=f"설정된 단축키: {' + '.join(self.hotkeys)}")
def reset_hotkey(self):
self.hotkeys.clear()
self.hotkey_label.config(text="현재 설정: 없음")
self.root.unbind_all("<KeyPress>")
def take_screenshot(self, event=None):
self.root.iconify()
time.sleep(0.5)
screenshot = pyautogui.screenshot()
save_name = time.strftime('%Y%m%d%H%M%S') + ".png"
save_path = os.path.join(os.getcwd(), save_name)
screenshot.save(save_path)
os.startfile(save_path)
self.root.deiconify()
# 실행
root = tk.Tk()
app = ScreenshotApp(root)
root.mainloop()
고도화결과
그럴싸하게 나온 듯 보이지만 실제 키입력이 잘 안 되는 현상이 발생하고 키조합으로 스크린샷이 되는게 아니고 각각 키에 스크린샷이 뜨는 결함이 나왔습니다. 다시 변경해 보도록 해보겠습니다.
고도화 2
키조합할 때 시프트키만 인식되고 컨트롤키 알트키는 인식이 되지 않았고 키조합은 한키를 누르기 시작한때부터 모든 키가 눌릴때까지 즉 최대 3개의 키가 눌린것까지를 조합으로 해주고 키업이 일어나는 순간의 조합으로 해줘 그리고 단축키를 입력할때도 모든키가 조합되지 않으면 스크린샷을 하지 않도록 변경해 줘
ChatGPT 결과
✅ 변경 완료! 이제 Shift, Ctrl, Alt 키도 정상적으로 감지되며, 최대 3개의 키 조합만 가능하게 설정되었습니다. 또한, 키 조합을 완료해야 저장할 수 있도록 했고, 설정 해제 버튼으로 쉽게 리셋할 수도 있습니다. 🚀
추가 수정이 필요하면 말해줘! 😊
여기까지 진행 후 수많은 디버깅과 수정결과 결국 완성은 했습니다.
정확한 설명을 해주고 소스의 상태를 파악해야 ChatGPT도 그에 맞게 변경을 해주는 현상을 발견했습니다.
과정이 길어 전부 담지는 못했으나
수정전 버전과 최종 버전을 올려드릴 테니 관심이 있으시면 수정전 버전으로 챗지피티에게 완성본을 얻어내는 과정을 경험해 보시면 좋을 것 같습니다. 3시간 넘게 수정을 했으나 챗지피티는 수정해야 하는 관점에서만 소스를 수정하는 특성이 있다는 걸 느낄 수 있었습니다. 결국 수정하다 다른 부분을 건드리는 케이스가 발견되었습니다.
최종 ChatGPT 결과도출 과정
이제 alt_l과 ctrl_l이 alt와 ctrl로 정상적으로 인식되도록 수정되었습니다.
또한, 단축키 입력 후 모든 키를 뗀 후에만 단축키가 확정되도록 했습니다.
설정된 단축키를 누르면 스크린샷이 정상적으로 작동하는지 확인해 보세요! 😊
나의 말:
디버그를 추가해줘
ChatGPT의 말:
디버깅 출력을 추가하여 키 입력과 저장된 단축키를 제대로 확인할 수 있도록 했습니다. 주요 변경 사항은 다음과 같습니다:
- detect_key 및 release_key에서 디버깅용 print 추가
- check_screenshot_key에서 눌린 키들과 저장된 단축키 비교 과정 로그 추가
수정된 전체 소스를 적용하겠습니다.
디버깅을 위한 출력 메시지를 추가했습니다.
이제 눌린 키, 설정된 단축키, 그리고 스크린샷 실행 여부를 로그로 확인할 수 있습니다.
테스트해보고 추가 수정이 필요하면 알려주세요!
나의 말:
ChatGPT의 말:
현재 코드는 개별 키 입력을 처리하는 방식이라 여러 개의 키를 동시에 눌러도 첫 번째 키만 감지됩니다. 이를 해결하기 위해 키를 누른 상태에서 대기하고, 모든 키를 놓았을 때 한 번만 비교하는 방식으로 수정하겠습니다.
수정 사항:
- pressed_keys를 제대로 활용 → 현재 눌린 모든 키를 저장하고, 키가 올라갈 때 최종적으로 비교
- check_screenshot_key 수정 → 눌린 키들이 설정된 단축키와 일치하는지 확인하는 방식 변경
이제 코드를 업데이트하겠습니다.
나의 말:
ChatGPT의 말:
수정해야 할 부분:
- check_screenshot_key에서 한 개의 키만 비교하는 문제
→ pressed_keys와 saved_hotkeys를 정확히 비교해야 함. - 모든 키가 눌린 후 놓았을 때 실행되도록 변경
→ 개별 KeyPress 이벤트가 아니라 모든 키가 놓인 후 실행되도록 수정.
이제 코드를 수정하겠습니다.
수정된 코드에서는 단축키가 제대로 입력되었을 때만 take_screenshot이 실행되도록 변경했습니다.
변경된 부분은 다음과 같습니다:
- check_screenshot_key()
- 기존에는 키를 하나만 확인했기 때문에 문제 발생
- 현재 눌린 모든 키(pressed_keys)를 saved_hotkeys와 비교하도록 수정
- 모든 키가 눌렸을 때 take_screenshot() 실행 후 screenshot_triggered = True로 변경
- release_screenshot_key 메서드 추가
- 키가 올라가면 screenshot_triggered를 False로 변경해 재입력을 허용
- pressed_keys에서 키를 제거하여 다음 입력 감지를 가능하게 함
이제 설정된 단축키가 동시에 눌렸을 때만 스크린샷이 찍힐 것입니다. 한 개의 키만 눌리면 실행되지 않고, 모든 키가 눌린 후에만 실행됩니다.
테스트해보시고 원하는 동작이 되는지 확인해 주세요! 🚀
나의 말:
단축키 설정할때 입력된 순서대로 설정되도록 해줘 그리고 모두 소문자로 적용해줘
ChatGPT의 말:
단축키가 입력된 순서를 유지하도록 변경하고, 모든 키를 소문자로 변환하도록 수정했습니다. 추가로 확인할 사항이 있으면 알려주세요!
최종결과
결과도출내용
alt와 ctrl을 인식하지 못하는 현상이 발생되어 디버깅해 보니
alt_l, ctrl_l 이렇게 left 키들을 인식 못했습니다.
해결방법은 치환해 주는 펑션을 만들라고 해 처리했습니다.
alt_l, ctrl_l 은 나중에 스크린샷을 찍을 때도 공통적으로 alt, ctrl로 변환해 비교해야 하는 부분도 주의하셔야 합니다.
즉 모든 키저장 키확인 부분에서 해당 키를 전환해 주는 게 필요합니다.
현재 설정 중에 나중에 입력한 d가 앞에 오는 현상은 잡았는데 다른 수정을 하다 보니 다시 원래대로 돌아와 있습니다. 이게 챗지피티의 아직까지의 한계인듯합니다. 작업을 하다 보면 다른 부분이 다시 안 되는 현상들이 자주 일어났습니다.
스크린을 찍을 때는 다행히도 세키를 다 눌러야 완벽하게 비교되어 창이 사라져서 스샷이 찍히고 다시 창이 나타나며 처리가 되었습니다.
왼쪽 디버깅한 것을 보시면 한 개 눌렀을 때 비교하고 키를 추가해서 또 비교하고 또 추가해서 비교해 마지막에 스크린이 찍힌 걸 확인할 수 있습니다.
조금 미숙한듯하지만 챗지피티에게 오랜 시간 설명해 주는 좋은 경험이 된 것 같습니다.
그럼 긴 글 읽어주셔서 감사합니다.
이제는 스샷을 잘 찍어 올릴 수 있게 됐네요 ㅎ
이상 IT아재였습니다.
'IT정보 > AI프로그래밍' 카테고리의 다른 글
이메일을 수집해서 엑셀파일로 관리하는 프로그램 (0) | 2025.03.17 |
---|---|
텍스트와 음성을 특정언어로 변환해주는 프로그램 만들기 (0) | 2025.03.16 |
내컴퓨터 정보확인하는 프로그램 (0) | 2025.03.14 |
QR코드를 만들어주는 프로그램 (0) | 2025.03.14 |
텍스트를 음성으로 음성을 텍스트로 변경하는 프로그램 (0) | 2025.03.13 |