이번엔 저번에 만든 가위바위보 게임 프로그램을 pyinstaller 사용해서 exe파일로 만들어봤다.
가위바위보 게임: https://jinho-study.tistory.com/1078
파이썬으로 가위바위보 게임 구현하기(Tkinter)
저번에는 tkinter(window, label, button, canvas)에 대해 알아보고 간단한 제비뽑기 프로그램을 만들었는데 https://jinho-study.tistory.com/1077 파이썬 GUI 기초 1(Tkinter ) 1 GUI란? GUI: 소프트웨어의 조..
jinho-study.tistory.com
아래는 전체 코드인데 파일 경로 부분에서 조금 추가된 것이 있다.
import tkinter
import random
# from functools import partial
from PIL import ImageTk
import os
# PyInstaller에 의해 임시폴더에서 실행될 경우 임시폴더로 접근하는 함수
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def click_btn(user_choice):
# 가위, 바위, 보 중 랜덤으로 하나 선택하고 com_rps_label에 출력
computer_choice = random.choice(["가위", "바위", "보"])
com_rps_label["text"] = computer_choice
com_rps_label.update()
# 사용자가 선택한 것을 user_rps_label에 출력
user_rps_label["text"] = user_choice
user_rps_label.update()
# 승패를 판별하고 result_label에 출력
res = ""
if computer_choice == user_choice:
res = "비김!"
else:
if user_choice == "가위":
res = "승리!" if computer_choice == "보" else "패배!"
elif user_choice == "바위":
res = "승리!" if computer_choice == "가위" else "패배!"
elif user_choice == "보":
res = "승리!" if computer_choice == "바위" else "패배!"
result_label["text"] = res
result_label.update()
if __name__ == "__main__":
root = tkinter.Tk()
root.title("가위바위보 프로그램")
root.resizable(False, False)
canvas = tkinter.Canvas(root, width=800, height=480)
canvas.pack()
# 이미지 파일에 따라 tkinter.PhotoImage가 잘 작동하지 않는 것 같다.
# ImageTk.PhotoImage 명령을 대신 사용했다.
# gazou = tkinter.PhotoImage(file="alphago.png")
gazou = ImageTk.PhotoImage(file=resource_path("alphago.png"))
canvas.create_image(400, 240, image=gazou)
# 컴퓨터, 사용자 라벨
com_label = tkinter.Label(root, text="컴퓨터", font=("Times New Roman", 55),
bg="white")
user_label = tkinter.Label(root, text="사용자", font=("Times New Roman", 55),
bg="white")
# 컴퓨터 가위, 바위, 보 라벨
com_rps_label = tkinter.Label(root, text="??", font=("Times New Roman", 55),
bg="white")
# 사용자 가위, 바위, 보 라벨
user_rps_label = tkinter.Label(root, text="??", font=("Times New Roman", 55),
bg="white")
# 승패 결과 라벨
result_label = tkinter.Label(root, text="승패", font=("Times New Roman", 60),
bg="white")
com_label.place(x=350, y=25)
com_rps_label.place(x=600, y=25)
user_label.place(x=350, y=145)
user_rps_label.place(x=600, y=145)
result_label.place(x=470, y=250)
# 가위, 바위, 보 버튼 3개
# 버튼 명령에 인수를 전달하기 위해 lambda를 사용했다.
# partial(clict_btn, "가위") 같은 방식으로도 사용할 수 있다.
s_button = tkinter.Button(root, text="가위", font=("Times New Roman", 36),
fg="skyblue", command=lambda: click_btn("가위"))
r_button = tkinter.Button(root, text="바위", font=("Times New Roman", 36),
fg="skyblue", command=lambda: click_btn("바위"))
p_button = tkinter.Button(root, text="보", font=("Times New Roman", 36),
fg="skyblue", command=lambda: click_btn("보"))
s_button.place(x=350, y=365)
r_button.place(x=520, y=365)
p_button.place(x=690, y=365)
root.mainloop()
파일 경로 문제
처음에 exe파일로 만드는 것은 바로 성공했는데 계속~~ 실행이 안됬었는데 이유를 찾아보니 파일 경로 문제였다.
pyinstaller로 만든 exe파일은 실행 시에 필요한 모든 파일을 임시 폴더에 풀어낸 후에 실행되는데,
이때 이 임시 폴더는 실행시마다 경로가 달라진다. 그래서 필요한 파일에 그냥 접근하면 오류가 나기에
sys._MEIPASS 라는 변수를 사용해서 접근해야 한다. 아래 글 덕분에 알게 되었다!
https://www.inflearn.com/questions/57133
이미지가 onefile로 안들어간거 같아요 - 인프런 | 질문 & 답변
[사진] 안녕하세요 강의 몇번씩 보고 있어요 pyautogui exe만들려고하는데요 이미지가 함께 안들어가는거 같아요 onefile로 했는데요 - 질문 & 답변 | 인프런...
www.inflearn.com
아래 함수를 사용해서 이미지를 불러오면 OK다.
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
pyinstaller 명령어
pyinstaller 명령어를 알아보자면
-w: 콘솔 윈도우 표시 안 함
-F: 1개의 exe파일로 변환
-i: 아이콘 설정
--add-data <SRC;DEST or SRC:DEST>: 파일 추가
등이 있는데 여기서 특히 --add-data는 데이터 유형에 따라 DEST가 다르다.
- Single file: "alphago.png:." -> DEST = .
- multiple files: "images/*.png:sfx" -> DEST = sfx
- folder: "images:data" -> DEST = data
추가로 직접 사용은 안 해봤지만 아래 같은 옵션들도 존재한다.
-n: 이름 지정
-D: 한 개 폴더로 변환
--hidden-import: 코드에서 직접적으로 보이지 않는 모듈 이름을 지정
아래 글을 참고했다!
https://stackoverflow.com/questions/41870727/pyinstaller-adding-data-files
Pyinstaller adding data files
I'm struggling with pyinstaller. Whenever I build this specific script with a kivy GUI and a .kv file, and run the .exe after the build, I get a fatal error: IOError: [Errno 2] No such file or dire...
stackoverflow.com
pyinstaller -w -F --add-data "alphago.png;." -i "icon.ico" rps_game.py
이제 위의 명령어를 실행하면 dist 폴더 안에 rps_game.exe 파일이 생긴 것을 확인할 수 있다.
아래 같이 아이콘도 잘 적용되었다. 아이콘 파일은 맨 위에 첨부했다!

만약 exe파일이 실행이 안된다면 필요한 데이터가 잘 추가되었는지, 현재 환경에 코드에 필요한 라이브러리가
다 설치가 되어있는 상태인지, resource_path 함수를 사용해서 데이터를 불러왔는지 등을 확인해주면 될 것 같다.
여기서 데이터가 잘 추가되었는지는 pyinstaller 명령어를 실행했을 때 생기는 .spec 파일을
열어보면 알 수 있는데, datas 쪽을 확인해주면 된다!
코드로 치기 귀찮으면 그냥 여기서 데이터를 직접 추가해줘도 된다.

추가로 아나콘다 환경에서 pyinstaller를 사용하면 exe파일의 용량이 엄청 커진다.
예를 들어 위의 가위바위보 게임을 exe파일로 생성했을 때 아나콘다에서는 74Mb인데
그냥 cmd에서 생성하면 12Mb이다. 이거에 대한 정확한 이유는 모르겠다만
내 아나콘다 환경에 쓸데없는 라이브러리가 많이 포함되어있어서 그런 것 같기도 하다.
github: https://github.com/kimjinho1/Python-Game
kimjinho1/Python-Game
Contribute to kimjinho1/Python-Game development by creating an account on GitHub.
github.com
'파이썬 게임 개발' 카테고리의 다른 글
파이썬으로 미로 게임 구현하기 2 (0) | 2021.06.29 |
---|---|
기본적인 게임 개발 기술(실시간 처리, 키 입력 받기, 미로 게임) (0) | 2021.06.28 |
파이썬 GUI 기초 2(Tkinter, 고양이 지수 진단 프로그램) (0) | 2021.06.24 |
파이썬으로 가위바위보 게임 구현하기(Tkinter) (0) | 2021.06.22 |
파이썬 GUI 기초 1(Tkinter, 제비뽑기 프로그램 ) (0) | 2021.06.20 |