//

"""
pip install pystray pillow pynput pywin32 
"""
from pynput.keyboard import Key, Listener
import msvcrt
import win32api, os, threading, signal, sys
import pystray
from PIL import Image, ImageDraw  #  Pillow 패키지


# //-----------------------------------------------------------------------------
# 키입력 처리
def on_press(key):
    print(f"{key} pressed")


def on_release(key):
    print(f"{key} released")
    if msvcrt.kbhit():  # 현재창의 키입력만 받음
        key = msvcrt.getch()
        if key == b"\x1b":  # ESC
            quit_app()


# //-----------------------------------------------------------------------------
tray_icon = None

# 아이콘 이미지 설정
# script_dir = os.path.dirname(os.path.abspath(__file__))
# image = Image.open(f"{script_dir}\\tray.ico")


# 아이콘 이미지 생성
def create_image(width, height, color1, color2):
    image = Image.new("RGB", (width, height), color1)
    dc = ImageDraw.Draw(image)
    dc.rectangle((width // 2, 0, width, height // 2), fill=color2)
    dc.rectangle((0, height // 2, width // 2, height), fill=color2)

    return image


image = create_image(64, 64, "yellow", "red")


def on_tray_show(icon, item):
    print("Show menu item clicked")


def on_tray_quit(icon, item):
    global tray_icon
    print("Quit menu item clicked", icon, item)

    # 종료시 아이콘 감춤
    if icon == None and item == None:
        tray_icon.stop()


def setup_tray():
    global tray_icon

    menu = pystray.Menu(pystray.MenuItem("Show", on_tray_show), pystray.MenuItem("Quit", on_tray_quit))

    tray_icon = pystray.Icon("MouseCatcher", image, "Mouse Catcher", menu)
    tray_icon.run()  # 아이콘 표시


def start_thread_tray():
    tray_thread = threading.Thread(target=setup_tray)
    tray_thread.start()


# //-----------------------------------------------------------------------------
# 종료 처리
def quit_app(call_quit=True):
    print("app 종료")

    # tray_icon.stop()  # 주의! 아이콘이 안 없어질때가 있음
    on_tray_quit(None, None)  # 여기서 stop()을 호출해야 아이콘이 없어짐

    if call_quit:
        print("quit")
        # SetConsoleCtrlHandler 를 통해 호출된 경우 종료코드를 실행하면 종료시간이 오래걸림
        # quit() # python 스크립트만 종료, 컴파일 할 경우에는 사용 불가
        # win32api.PostQuitMessage(0)
        sys.exit()  # 사용 권장


def on_win_close(sig, func=None):
    print("Console window closing, performing cleanup...")
    quit_app(False)
    return True  # Other handlers would be executed otherwise


# //-----------------------------------------------------------------------------

if __name__ == "__main__":
    win32api.SetConsoleCtrlHandler(on_win_close, True)  # 윈도우 닫기 버튼 처리

    start_thread_tray()

    # 전역 키보드 이벤트 모니터링
    with Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()

    print("종료됨")

//

반응형
Posted by codens